fd3470c146a2d77c8e329a70403c765385b20b60
1 /* pdp1_sys.c: PDP-1 simulator interface
3 Copyright (c) 1993-2007, 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-Jan-07 RMS Fixed bugs in block loader, char input
27 21-Dec-06 RMS Added 16-channel sequence break support, PDP-1D support
28 06-Apr-04 RMS Fixed bug in binary loader (found by Mark Crispin)
29 08-Feb-04 PLB Merged display support
30 08-Dec-03 RMS Added parallel drum support, drum mnemonics
31 18-Oct-03 RMS Added DECtape off reel message
32 01-Sep-03 RMS Added support for loading in multiple fields
33 22-Jul-03 RMS Updated for "hardware" RIM loader
34 05-Dec-02 RMS Added drum support
35 21-Nov-02 RMS Changed typewriter to half duplex
36 20-Aug-02 RMS Added DECtape support
37 17-Sep-01 RMS Removed multiconsole support
38 13-Jul-01 RMS Fixed RIM loader format
39 27-May-01 RMS Added multiconsole support
40 14-Mar-01 RMS Revised load/dump interface (again)
41 30-Oct-00 RMS Added support for examine to file
42 27-Oct-98 RMS V2.4 load interface
43 20-Oct-97 RMS Fixed endian-dependence in RIM loader
44 (found by Michael Somos)
47 #include "pdp1_defs.h"
50 extern DEVICE cpu_dev
;
51 extern DEVICE clk_dev
;
52 extern DEVICE ptr_dev
;
53 extern DEVICE ptp_dev
;
54 extern DEVICE tti_dev
;
55 extern DEVICE tto_dev
;
56 extern DEVICE lpt_dev
;
58 extern DEVICE drm_dev
;
59 extern DEVICE drp_dev
;
60 extern DEVICE dcs_dev
, dcsl_dev
;
61 extern DEVICE dpy_dev
;
66 extern int32 ascii_to_fiodec
[], fiodec_to_ascii
[];
67 extern int32 sc_map
[];
68 extern int32 sim_switches
;
70 /* SCP data structures and interface routines
72 sim_name simulator name string
73 sim_PC pointer to saved PC register descriptor
74 sim_emax number of words for examine
75 sim_devices array of pointers to simulated devices
76 sim_stop_messages array of pointers to stop messages
77 sim_load binary loader
80 char sim_name
[] = "PDP-1";
82 REG
*sim_PC
= &cpu_reg
[0];
86 DEVICE
*sim_devices
[] = {
103 const char *sim_stop_messages
[] = {
105 "Undefined instruction",
109 "Nested indirect addresses",
110 "Infinite I/O wait state",
114 /* Binary loader - supports both RIM format and Macro block format */
116 int32
pdp1_getw (FILE *inf
)
121 for (i
= 0; i
< 3;) {
122 if ((tmp
= getc (inf
)) == EOF
) return -1;
124 word
= (word
<< 6) | (tmp
& 077);
131 t_stat
rim_load (FILE *inf
, int32 fld
)
136 if ((val
= pdp1_getw (inf
)) < 0) return SCPE_FMT
;
137 if (((val
& 0760000) == OP_DIO
) || /* DIO? */
138 ((val
& 0760000) == OP_DAC
)) { /* hack - Macro1 err */
139 origin
= val
& DAMASK
;
140 if ((val
= pdp1_getw (inf
)) < 0) return SCPE_FMT
;
141 M
[fld
| origin
] = val
;
143 else if ((val
& 0760000) == OP_JMP
) { /* JMP? */
144 PC
= fld
| (val
& DAMASK
);
147 else return SCPE_FMT
; /* bad instr */
149 return SCPE_OK
; /* done */
152 t_stat
blk_load (FILE *inf
, int32 fld
)
154 int32 val
, start
, count
, csum
;
157 if ((val
= pdp1_getw (inf
)) < 0) return SCPE_FMT
; /* get word, EOF? */
158 if ((val
& 0760000) == OP_DIO
) { /* DIO? */
159 csum
= val
; /* init checksum */
160 start
= val
& DAMASK
; /* starting addr */
161 if ((val
= pdp1_getw (inf
)) < 0) return SCPE_FMT
;
162 if ((val
& 0760000) != OP_DIO
) return SCPE_FMT
;
164 if (csum
> DMASK
) csum
= (csum
+ 1) & DMASK
;
165 count
= (val
& DAMASK
) - start
; /* block count */
166 if (count
<= 0) return SCPE_FMT
;
167 while (count
--) { /* loop on data */
168 if ((val
= pdp1_getw (inf
)) < 0) return SCPE_FMT
;
170 if (csum
> DMASK
) csum
= (csum
+ 1) & DMASK
;
171 M
[fld
| start
] = val
;
172 start
= (start
+ 1) & DAMASK
;
174 if ((val
= pdp1_getw (inf
)) < 0) return SCPE_FMT
;
175 if (val
!= csum
) return SCPE_CSUM
;
177 else if ((val
& 0760000) == OP_JMP
) { /* JMP? */
178 PC
= fld
| (val
& DAMASK
);
181 else return SCPE_FMT
; /* bad instr */
183 return SCPE_OK
; /* done */
186 t_stat
sim_load (FILE *fileref
, char *cptr
, char *fnam
, int flag
)
191 if (flag
!= 0) return SCPE_ARG
;
192 if (cptr
&& (*cptr
!= 0)) {
193 fld
= get_uint (cptr
, 8, AMASK
, &sta
);
194 if (sta
!= SCPE_OK
) return sta
;
198 sta
= rim_load (fileref
, fld
);
199 if (sta
!= SCPE_OK
) return sta
;
200 if ((sim_switches
& SWMASK ('B')) || match_ext (fnam
, "BIN"))
201 return blk_load (fileref
, fld
);
207 #define I_V_FL 18 /* inst class */
208 #define I_M_FL 017 /* class mask */
209 #define I_V_NPN 0 /* no operand */
210 #define I_V_IOT 1 /* IOT */
211 #define I_V_LAW 2 /* LAW */
212 #define I_V_MRF 3 /* memory reference */
213 #define I_V_MRI 4 /* mem ref no ind */
214 #define I_V_OPR 5 /* OPR */
215 #define I_V_SKP 6 /* skip */
216 #define I_V_SHF 7 /* shift */
217 #define I_V_SPC 8 /* special */
218 #define I_NPN (I_V_NPN << I_V_FL) /* no operand */
219 #define I_IOT (I_V_IOT << I_V_FL) /* IOT */
220 #define I_LAW (I_V_LAW << I_V_FL) /* LAW */
221 #define I_MRF (I_V_MRF << I_V_FL) /* memory reference */
222 #define I_MRI (I_V_MRI << I_V_FL) /* mem ref no ind */
223 #define I_OPR (I_V_OPR << I_V_FL) /* OPR */
224 #define I_SKP (I_V_SKP << I_V_FL) /* skip */
225 #define I_SHF (I_V_SHF << I_V_FL) /* shift */
226 #define I_SPC (I_V_SPC << I_V_FL)
228 static const int32 masks
[] = {
229 0777777, 0760077, 0760000, 0760000,
230 0770000, 0760017, 0760077, 0777000,
234 static const char *opcode
[] = {
235 "AND", "IOR", "XOR", "XCT", /* mem refs */
236 "LAC", "LIO", "DAC", "DAP",
237 "DIP", "DIO", "DZM", "ADD",
238 "SUB", "IDX", "ISP", "SAD",
239 "SAS", "MUL", "DIV", "JMP",
240 "JSP", "LCH", "DCH", "TAD",
242 "CAL", "JDA", /* mem ref no ind */
246 "IOH", "RPA", "RPB", "RRB", /* I/O instructions */
247 "PPA", "PPB", "TYO", "TYI",
249 "DSC", "ASC", "ISC", "CAC",
252 "MSE", "MLC", "MRD", "MWR", "MRS",
253 "DIA", "DBA", "DWC", "DRA", "DCL",
254 "DRD", "DWR", "DBL", "DCN",
256 "LRG", "ERG", "LRM", "ERM",
257 "RNM", "RSM", "RCK", "CTB",
258 "RCH", "RCC", "TCC", "TCB",
261 "SKP", "SKP I", "CLO", /* base as NPNs */
264 "RAL", "RIL", "RCL", /* shifts */
269 "SZF1", "SZF2", "SZF3", /* skips */
270 "SZF4", "SZF5", "SZF6", "SZF7",
271 "SZS1", "SZS1 SZF1", "SZS1 SZF2", "SZS1 SZ3",
272 "SZS1 SZF4", "SZS1 SZF5", "SZS1 SZF6", "SZS1 SZF7",
273 "SZS2", "SZS2 SZF1", "SZS2 SZF2", "SZS2 SZ3",
274 "SZS2 SZF4", "SZS2 SZF5", "SZS2 SZF6", "SZS2 SZF7",
275 "SZS3", "SZS3 SZF1", "SZS3 SZF2", "SZS3 SZ3",
276 "SZS3 SZF4", "SZS3 SZF5", "SZS3 SZF6", "SZS3 SZF7",
277 "SZS4", "SZS4 SZF1", "SZS4 SZF2", "SZS4 SZ3",
278 "SZS4 SZF4", "SZS4 SZF5", "SZS4 SZF6", "SZS4 SZF7",
279 "SZS5", "SZS5 SZF1", "SZS5 SZF2", "SZS5 SZ3",
280 "SZS5 SZF4", "SZS5 SZF5", "SZS5 SZF6", "SZS5 SZF7",
281 "SZS6", "SZS6 SZF1", "SZS6 SZF2", "SZS6 SZ3",
282 "SZS6 SZF4", "SZS6 SZF5", "SZS6 SZF6", "SZS6 SZF7",
283 "SZS7", "SZS7 SZF1", "SZS7 SZF2", "SZS7 SZ3",
284 "SZS7 SZF4", "SZS7 SZF5", "SZS7 SZF6", "SZS7 SZF7",
286 "CLF1", "CLF2", "CLF3", /* operates */
287 "CLF4", "CLF5", "CLF6", "CLF7",
288 "STF1", "STF2", "STF3",
289 "STF4", "STF5", "STF6", "STF7",
291 "FF1", "FF2", "FF3", /* specials */
293 "SZA", "SPA", "SMA", /* uprog skips */
295 "I", /* encode only */
297 "LIA", "LAI", "SWP", /* uprog opers */
302 "CML", "CLL", "SZL", /* uprog specials */
307 NULL
, NULL
, NULL
, /* decode only */
311 static const int32 opc_val
[] = {
312 0020000+I_MRF
, 0040000+I_MRF
, 0060000+I_MRF
, 0100000+I_MRF
,
313 0200000+I_MRF
, 0220000+I_MRF
, 0240000+I_MRF
, 0260000+I_MRF
,
314 0300000+I_MRF
, 0320000+I_MRF
, 0340000+I_MRF
, 0400000+I_MRF
,
315 0420000+I_MRF
, 0440000+I_MRF
, 0460000+I_MRF
, 0500000+I_MRF
,
316 0520000+I_MRF
, 0540000+I_MRF
, 0560000+I_MRF
, 0600000+I_MRF
,
317 0620000+I_MRF
, 0120000+I_MRF
, 0140000+I_MRF
, 0360000+I_MRF
,
319 0160000+I_MRI
, 0170000+I_MRI
,
323 0730000+I_NPN
, 0720001+I_IOT
, 0720002+I_IOT
, 0720030+I_IOT
,
324 0720005+I_IOT
, 0720006+I_IOT
, 0720003+I_IOT
, 0720004+I_IOT
,
326 0720050+I_IOT
, 0720051+I_IOT
, 0720052+I_IOT
, 0720053+I_NPN
,
327 0720054+I_NPN
, 0720055+I_NPN
, 0720056+I_NPN
,
328 0720074+I_NPN
, 0724074+I_NPN
, 0720033+I_NPN
,
329 0720301+I_NPN
, 0720401+I_NPN
, 0720501+I_NPN
, 0720601+I_NPN
, 0720701+I_NPN
,
330 0720061+I_NPN
, 0722061+I_NPN
, 0720062+I_NPN
, 0722062+I_NPN
, 0720063+I_NPN
,
331 0720161+I_NPN
, 0721161+I_NPN
, 0720162+I_NPN
, 0721162+I_NPN
,
332 0720163+I_NPN
, 0720164+I_NPN
, 0721164+I_NPN
,
333 0720010+I_NPN
, 0720011+I_NPN
, 0720064+I_NPN
, 0720065+I_NPN
,
334 0720066+I_IOT
, 0720067+I_NPN
, 0720032+I_NPN
, 0720035+I_NPN
,
335 0720022+I_NPN
, 0721022+I_NPN
, 0725022+I_NPN
, 0724022+I_NPN
,
336 0720122+I_NPN
, 0724122+I_NPN
, 0721122+I_NPN
,
338 0640000+I_NPN
, 0650000+I_NPN
, 0651600+I_NPN
,
339 0660000+I_NPN
, 0740000+I_NPN
, 0760000+I_NPN
,
341 0661000+I_SHF
, 0662000+I_SHF
, 0663000+I_SHF
,
342 0665000+I_SHF
, 0666000+I_SHF
, 0667000+I_SHF
,
343 0671000+I_SHF
, 0672000+I_SHF
, 0673000+I_SHF
,
344 0675000+I_SHF
, 0676000+I_SHF
, 0677000+I_SHF
,
346 0640001+I_SKP
, 0640002+I_SKP
, 0640003+I_SKP
,
347 0640004+I_SKP
, 0640005+I_SKP
, 0640006+I_SKP
, 0640007+I_SKP
,
348 0640010+I_SKP
, 0640011+I_SKP
, 0640012+I_SKP
, 0640013+I_SKP
,
349 0640014+I_SKP
, 0640015+I_SKP
, 0640016+I_SKP
, 0640017+I_SKP
,
350 0640020+I_SKP
, 0640021+I_SKP
, 0640022+I_SKP
, 0640023+I_SKP
,
351 0640024+I_SKP
, 0640025+I_SKP
, 0640026+I_SKP
, 0640027+I_SKP
,
352 0640030+I_SKP
, 0640031+I_SKP
, 0640032+I_SKP
, 0640033+I_SKP
,
353 0640034+I_SKP
, 0640035+I_SKP
, 0640036+I_SKP
, 0640037+I_SKP
,
354 0640040+I_SKP
, 0640041+I_SKP
, 0640042+I_SKP
, 0640043+I_SKP
,
355 0640044+I_SKP
, 0640045+I_SKP
, 0640046+I_SKP
, 0640047+I_SKP
,
356 0640050+I_SKP
, 0640051+I_SKP
, 0640052+I_SKP
, 0640053+I_SKP
,
357 0640054+I_SKP
, 0640055+I_SKP
, 0640056+I_SKP
, 0640057+I_SKP
,
358 0640060+I_SKP
, 0640061+I_SKP
, 0640062+I_SKP
, 0640063+I_SKP
,
359 0640064+I_SKP
, 0640065+I_SKP
, 0640066+I_SKP
, 0640067+I_SKP
,
360 0640070+I_SKP
, 0640071+I_SKP
, 0640072+I_SKP
, 0640073+I_SKP
,
361 0640074+I_SKP
, 0640075+I_SKP
, 0640076+I_SKP
, 0640077+I_SKP
,
363 0760001+I_OPR
, 0760002+I_OPR
, 0760003+I_OPR
,
364 0760004+I_OPR
, 0760005+I_OPR
, 0760006+I_OPR
, 0760007+I_OPR
,
365 0760011+I_OPR
, 0760012+I_OPR
, 0760013+I_OPR
,
366 0760014+I_OPR
, 0760015+I_OPR
, 0760016+I_OPR
, 0760017+I_OPR
,
368 0740001+I_SPC
, 0740002+I_SPC
, 0740003+I_OPR
,
370 0640100+I_SKP
, 0640200+I_SKP
, 0640400+I_SKP
,
371 0641000+I_SKP
, 0642000+I_SKP
, 0644000+I_SKP
,
372 0010000+I_SKP
, /* encode only */
374 0760020+I_OPR
, 0760040+I_OPR
, 0760060+I_NPN
,
375 0760100+I_OPR
, 0760200+I_OPR
, 0760400+I_OPR
,
376 0761000+I_OPR
, 0762000+I_OPR
, 0764000+I_OPR
,
379 0740004+I_SPC
, 0740010+I_SPC
, 0740020+I_SPC
,
380 0740040+I_SPC
, 0740100+I_SPC
, 0740200+I_SPC
,
381 0740400+I_SPC
, 0741000+I_SPC
, 0742000+I_SPC
,
384 0640000+I_SKP
, 0740000+I_SPC
, 0760000+I_OPR
, /* decode only */
388 /* Operate or skip decode
393 class = instruction class code
396 status = space needed?
399 int32
fprint_opr (FILE *of
, int32 inst
, int32
class, int32 sp
)
403 for (i
= 0; opc_val
[i
] >= 0; i
++) { /* loop thru ops */
404 j
= (opc_val
[i
] >> I_V_FL
) & I_M_FL
; /* get class */
405 if ((j
== class) && (opc_val
[i
] & inst
)) { /* same class? */
406 inst
= inst
& ~opc_val
[i
]; /* mask bit set? */
407 fprintf (of
, (sp
? " %s": "%s"), opcode
[i
]);
419 *val = pointer to values
420 *uptr = pointer to unit
426 #define FMTASC(x) ((x) < 040)? "<%03o>": "%c", (x)
427 #define SIXTOASC(x) fiodec_to_ascii[x]
428 #define ASCTOSIX(x) (ascii_to_fiodec[x] & 077)
430 t_stat
fprint_sym (FILE *of
, t_addr addr
, t_value
*val
,
431 UNIT
*uptr
, int32 sw
)
433 int32 cflag
, i
, j
, sp
, inst
, disp
, ma
;
436 cflag
= (uptr
== NULL
) || (uptr
== &cpu_unit
);
437 if (sw
& SWMASK ('A')) { /* ASCII? */
438 if (inst
> 0377) return SCPE_ARG
;
439 fprintf (of
, FMTASC (inst
& 0177));
442 if (sw
& SWMASK ('F')) {
443 fputc (fiodec_to_ascii
[inst
& 077], of
);
446 if (sw
& SWMASK ('C')) { /* character? */
447 fprintf (of
, "%c", SIXTOASC ((inst
>> 12) & 077));
448 fprintf (of
, "%c", SIXTOASC ((inst
>> 6) & 077));
449 fprintf (of
, "%c", SIXTOASC (inst
& 077));
452 if (!(sw
& SWMASK ('M'))) return SCPE_ARG
;
454 /* Instruction decode */
456 disp
= inst
& 007777;
457 ma
= (addr
& EPCMASK
) | disp
;
458 for (i
= 0; opc_val
[i
] >= 0; i
++) { /* loop thru ops */
459 j
= (opc_val
[i
] >> I_V_FL
) & I_M_FL
; /* get class */
460 if ((opc_val
[i
] & DMASK
) == (inst
& masks
[j
])) { /* match? */
462 switch (j
) { /* case on class */
464 case I_V_NPN
: /* no operands */
465 fprintf (of
, "%s", opcode
[i
]); /* opcode */
468 case I_V_IOT
: /* IOT */
469 disp
= (inst
- opc_val
[i
]) & 017777;
470 if (disp
== IA
) fprintf (of
, "%s I", opcode
[i
]);
471 else if (disp
) fprintf (of
, "%s %-o", opcode
[i
], disp
);
472 else fprintf (of
, "%s", opcode
[i
]);
475 case I_V_LAW
: /* LAW */
476 cflag
= 0; /* fall thru to MRF */
477 case I_V_MRF
: /* mem ref */
478 fprintf (of
, "%s%s%-o", opcode
[i
],
479 ((inst
& IA
)? " I ": " "), (cflag
? ma
: disp
));
482 case I_V_MRI
: /* mem ref no ind */
483 fprintf (of
, "%s %-o", opcode
[i
], (cflag
? ma
: disp
));
486 case I_V_OPR
: /* operates */
487 sp
= fprint_opr (of
, inst
& 017760, j
, 0);
488 if (opcode
[i
]) fprintf (of
, (sp
? " %s": "%s"), opcode
[i
]);
491 case I_V_SKP
: /* skips */
492 sp
= fprint_opr (of
, inst
& 007700, j
, 0);
493 if (opcode
[i
]) sp
= fprintf (of
, (sp
? " %s": "%s"), opcode
[i
]);
494 if (inst
& IA
) fprintf (of
, sp
? " I": "I");
497 case I_V_SPC
: /* specials */
498 sp
= fprint_opr (of
, inst
& 007774, j
, 0);
499 if (opcode
[i
]) sp
= fprintf (of
, (sp
? " %s": "%s"), opcode
[i
]);
500 if (inst
& IA
) fprintf (of
, sp
? " I": "I");
503 case I_V_SHF
: /* shifts */
504 fprintf (of
, "%s %-d", opcode
[i
], sc_map
[inst
& 0777]);
514 /* Get 18b signed number
517 *cptr = pointer to input string
518 *sign = pointer to sign
519 *status = pointer to error status
524 t_value
get_sint (char *cptr
, int32
*sign
, t_stat
*status
)
531 else if (*cptr
== '-') {
535 return get_uint (cptr
, 8, DMASK
, status
);
541 *cptr = pointer to input string
543 uptr = pointer to unit
544 *val = pointer to output values
547 status = error status
550 t_stat
parse_sym (char *cptr
, t_addr addr
, UNIT
*uptr
, t_value
*val
, int32 sw
)
552 int32 cflag
, d
, i
, j
, k
, sign
;
554 static int32 sc_enc
[10] = { 0, 01, 03, 07, 017, 037, 077, 0177, 0377, 0777 };
557 cflag
= (uptr
== NULL
) || (uptr
== &cpu_unit
);
558 while (isspace (*cptr
)) cptr
++;
559 for (i
= 1; (i
< 3) && (cptr
[i
] != 0); i
++)
560 if (cptr
[i
] == 0) for (j
= i
+ 1; j
<= 3; j
++) cptr
[j
] = 0;
561 if ((sw
& SWMASK ('A')) || ((*cptr
== '\'') && cptr
++)) { /* ASCII char? */
562 if (cptr
[0] == 0) return SCPE_ARG
; /* must have 1 char */
563 val
[0] = (t_value
) cptr
[0];
566 if ((sw
& SWMASK ('C')) || ((*cptr
== '"') && cptr
++)) { /* sixbit string? */
567 if (cptr
[0] == 0) return SCPE_ARG
; /* must have 1 char */
568 val
[0] = ((ASCTOSIX (cptr
[0]) & 077) << 12) |
569 ((ASCTOSIX (cptr
[1]) & 077) << 6) |
570 (ASCTOSIX (cptr
[2]) & 077);
574 cptr
= get_glyph (cptr
, gbuf
, 0); /* get opcode */
575 for (i
= 0; (opcode
[i
] != NULL
) && (strcmp (opcode
[i
], gbuf
) != 0) ; i
++) ;
576 if (opcode
[i
] == NULL
) return SCPE_ARG
;
577 val
[0] = opc_val
[i
] & DMASK
; /* get value */
578 j
= (opc_val
[i
] >> I_V_FL
) & I_M_FL
; /* get class */
580 switch (j
) { /* case on class */
582 case I_V_LAW
: /* LAW */
583 cflag
= 0; /* fall through */
584 case I_V_MRF
: case I_V_MRI
: /* mem ref */
585 cptr
= get_glyph (cptr
, gbuf
, 0); /* get next field */
586 if ((j
!= I_V_MRI
) && strcmp (gbuf
, "I") == 0) { /* indirect? */
587 val
[0] = val
[0] | IA
;
588 cptr
= get_glyph (cptr
, gbuf
, 0);
590 d
= get_uint (gbuf
, 8, AMASK
, &r
);
591 if (r
!= SCPE_OK
) return SCPE_ARG
;
592 if (d
<= DAMASK
) val
[0] = val
[0] | d
;
593 else if (cflag
&& (((addr
^ d
) & EPCMASK
) == 0))
594 val
[0] = val
[0] | (d
& DAMASK
);
595 else return SCPE_ARG
;
598 case I_V_SHF
: /* shift */
599 cptr
= get_glyph (cptr
, gbuf
, 0);
600 d
= get_uint (gbuf
, 10, 9, &r
);
601 if (r
!= SCPE_OK
) return SCPE_ARG
;
602 val
[0] = val
[0] | sc_enc
[d
];
605 case I_V_NPN
: case I_V_IOT
:
606 case I_V_OPR
: case I_V_SKP
: case I_V_SPC
:
607 for (cptr
= get_glyph (cptr
, gbuf
, 0); gbuf
[0] != 0;
608 cptr
= get_glyph (cptr
, gbuf
, 0)) {
609 for (i
= 0; (opcode
[i
] != NULL
) &&
610 (strcmp (opcode
[i
], gbuf
) != 0); i
++) ;
611 if (opcode
[i
] != NULL
) {
612 k
= opc_val
[i
] & DMASK
;
613 if ((k
!= IA
) && (((k
^ val
[0]) & 0760000) != 0))
618 d
= get_sint (gbuf
, &sign
, &r
);
619 if (r
!= SCPE_OK
) return SCPE_ARG
;
620 if (sign
== 0) val
[0] = val
[0] + d
;
621 else if (sign
< 0) val
[0] = val
[0] - d
;
622 else val
[0] = val
[0] | d
;
627 if (*cptr
!= 0) return SCPE_ARG
; /* junk at end? */