1 /* pdp10_sys.c: PDP-10 simulator interface
2
3 Copyright (c) 1993-2011, Robert M Supnik
4
5 Permission is hereby granted, free of charge, to any person obtaining a
6 copy of this software and associated documentation files (the "Software"),
7 to deal in the Software without restriction, including without limitation
8 the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 and/or sell copies of the Software, and to permit persons to whom the
10 Software is furnished to do so, subject to the following conditions:
11
12 The above copyright notice and this permission notice shall be included in
13 all copies or substantial portions of the Software.
14
15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 ROBERT M SUPNIK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
22 Except as contained in this notice, the name of Robert M Supnik shall not be
23 used in advertising or otherwise to promote the sale, use or other dealings
24 in this Software without prior written authorization from Robert M Supnik.
25
26 04-Apr-11 RMS Removed DEUNA/DELUA support - never implemented
27 01-Feb-07 RMS Added CD support
28 22-Jul-05 RMS Fixed warning from Solaris C (from Doug Gwyn)
29 09-Jan-03 RMS Added DEUNA/DELUA support
30 12-Sep-02 RMS Added RX211 support
31 22-Apr-02 RMS Removed magtape record length error
32 17-Sep-01 RMS Removed multiconsole support
33 25-Aug-01 RMS Enabled DZ11
34 27-May-01 RMS Added multiconsole support
35 29-Apr-01 RMS Fixed format for RDPCST, WRPCST
36 Added CLRCSH for ITS
37 03-Apr-01 RMS Added support for loading EXE files
38 19-Mar-01 RMS Added support for loading SAV files
39 30-Oct-00 RMS Added support for examine to file
40 */
41
42 #include "pdp10_defs.h"
43 #include <ctype.h>
44
45 extern DEVICE cpu_dev;
46 extern DEVICE pag_dev;
47 extern DEVICE tim_dev;
48 extern DEVICE fe_dev;
49 extern DEVICE uba_dev;
50 extern DEVICE ptr_dev;
51 extern DEVICE ptp_dev;
52 extern DEVICE rp_dev;
53 extern DEVICE tu_dev;
54 extern DEVICE dz_dev;
55 extern DEVICE ry_dev;
56 extern DEVICE cr_dev;
57 extern DEVICE lp20_dev;
58 extern UNIT cpu_unit;
59 extern REG cpu_reg[];
60 extern d10 *M;
61 extern a10 saved_PC;
62
63 /* SCP data structures and interface routines
64
65 sim_name simulator name string
66 sim_PC pointer to saved PC register descriptor
67 sim_emax number of words for examine
68 sim_devices array of pointers to simulated devices
69 sim_stop_messages array of pointers to stop messages
70 sim_load binary loader
71 */
72
73 char sim_name[] = "PDP-10";
74
75 REG *sim_PC = &cpu_reg[0];
76
77 int32 sim_emax = 1;
78
79 DEVICE *sim_devices[] = {
80 &cpu_dev,
81 &pag_dev,
82 &tim_dev,
83 &fe_dev,
84 &uba_dev,
85 &ptr_dev,
86 &ptp_dev,
87 &ry_dev,
88 &lp20_dev,
89 &cr_dev,
90 &rp_dev,
91 &tu_dev,
92 &dz_dev,
93 NULL
94 };
95
96 const char *sim_stop_messages[] = {
97 "Unknown error",
98 "HALT instruction",
99 "Breakpoint",
100 "Illegal instruction",
101 "Illegal interrupt instruction",
102 "Paging error in interrupt",
103 "Zero vector table",
104 "NXM on UPT/EPT reference",
105 "Nested indirect address limit exceeded",
106 "Nested XCT limit exceeded",
107 "Invalid I/O controller",
108 "Address stop",
109 "Panic stop"
110 };
111
112 /* Binary loader, supports RIM10, SAV, EXE */
113
114 #define FMT_R 1 /* RIM10 */
115 #define FMT_S 2 /* SAV */
116 #define FMT_E 3 /* EXE */
117
118 #define EXE_DIR 01776 /* EXE directory */
119 #define EXE_VEC 01775 /* EXE entry vec */
120 #define EXE_PDV 01774 /* EXE ignored */
121 #define EXE_END 01777 /* EXE end
122
123 /* RIM10 loader
124
125 RIM10 format is a binary paper tape format (all data frames
126 are 200 or greater). It consists of blocks containing
127
128 -count,,origin-1
129 word
130 :
131 word
132 checksum (includes IOWD)
133 :
134 JRST start
135 */
136
getrimw(FILE * fileref)137 d10 getrimw (FILE *fileref)
138 {
139 int32 i, tmp;
140 d10 word;
141
142 word = 0;
143 for (i = 0; i < 6;) {
144 if ((tmp = getc (fileref)) == EOF)
145 return -1;
146 if (tmp & 0200) {
147 word = (word << 6) | ((d10) tmp & 077);
148 i++;
149 }
150 }
151 return word;
152 }
153
load_rim(FILE * fileref)154 t_stat load_rim (FILE *fileref)
155 {
156 d10 count, cksm, data;
157 a10 pa;
158 int32 op;
159
160 for ( ;; ) { /* loop until JRST */
161 count = cksm = getrimw (fileref); /* get header */
162 if (count < 0) /* read err? */
163 return SCPE_FMT;
164 if (TSTS (count)) { /* hdr = IOWD? */
165 for ( ; TSTS (count); count = AOB (count)) {
166 data = getrimw (fileref); /* get data wd */
167 if (data < 0)
168 return SCPE_FMT;
169 cksm = cksm + data; /* add to cksm */
170 pa = ((a10) count + 1) & AMASK; /* store */
171 M[pa] = data;
172 } /* end for */
173 data = getrimw (fileref); /* get cksm */
174 if (data < 0)
175 return SCPE_FMT;
176 if ((cksm + data) & DMASK) /* test cksm */
177 return SCPE_CSUM;
178 } /* end if count */
179 else {
180 op = GET_OP (count); /* not IOWD */
181 if (op != OP_JRST) /* JRST? */
182 return SCPE_FMT;
183 saved_PC = (a10) count & AMASK; /* set PC */
184 break;
185 } /* end else */
186 } /* end for */
187 return SCPE_OK;
188 }
189
190 /* SAV file loader
191
192 SAV format is a disk file format (36b words). It consists of
193 blocks containing:
194
195 -count,,origin-1
196 word
197 :
198 word
199 :
200 JRST start
201 */
202
load_sav(FILE * fileref)203 t_stat load_sav (FILE *fileref)
204 {
205 d10 count, data;
206 a10 pa;
207 int32 wc, op;
208
209 for ( ;; ) { /* loop */
210 wc = fxread (&count, sizeof (d10), 1, fileref); /* read IOWD */
211 if (wc == 0) /* done? */
212 return SCPE_OK;
213 if (TSTS (count)) { /* IOWD? */
214 for ( ; TSTS (count); count = AOB (count)) {
215 wc = fxread (&data, sizeof (d10), 1, fileref);
216 if (wc == 0)
217 return SCPE_FMT;
218 pa = ((a10) count + 1) & AMASK; /* store data */
219 M[pa] = data;
220 } /* end for */
221 } /* end if count*/
222 else {
223 op = GET_OP (count); /* not IOWD */
224 if (op != OP_JRST) /* JRST? */
225 return SCPE_FMT;
226 saved_PC = (a10) count & AMASK; /* set PC */
227 break;
228 } /* end else */
229 } /* end for */
230 return SCPE_OK;
231 }
232
233 /* EXE file loader
234
235 EXE format is a disk file format (36b words). It consists of
236 blocks containing:
237
238 block type,,total words = n
239 n - 1 data words
240
241 Block types are
242
243 EXE_DIR (1776) directory
244 EXE_VEC (1775) entry vector
245 EXE_PDV (1774) optional blocks
246 EXE_END (1777) end block
247
248 The directory blocks are the most important and contain doubleword
249 page loading information:
250
251 word0<0:8> = flags
252 <9:35> = page in file (0 if 0 page)
253 word1<0:8> = repeat count - 1
254 <9:35> = page in memory
255 */
256
257 #define DIRSIZ (2 * PAG_SIZE)
258
load_exe(FILE * fileref)259 t_stat load_exe (FILE *fileref)
260 {
261 d10 data, dirbuf[DIRSIZ], pagbuf[PAG_SIZE], entbuf[2];
262 int32 ndir, entvec, i, j, k, cont, bsz, bty, rpt, wc;
263 int32 fpage, mpage;
264 a10 ma;
265
266 ndir = entvec = 0; /* no dir, entvec */
267 cont = 1;
268 do {
269 wc = fxread (&data, sizeof (d10), 1, fileref); /* read blk hdr */
270 if (wc == 0) /* error? */
271 return SCPE_FMT;
272 bsz = (int32) ((data & RMASK) - 1); /* get count */
273 if (bsz <= 0) /* zero? */
274 return SCPE_FMT;
275 bty = (int32) LRZ (data); /* get type */
276 switch (bty) { /* case type */
277
278 case EXE_DIR: /* directory */
279 if (ndir) /* got one */
280 return SCPE_FMT;
281 ndir = fxread (dirbuf, sizeof (d10), bsz, fileref);
282 if (ndir < bsz) /* error */
283 return SCPE_FMT;
284 break;
285
286 case EXE_PDV: /* ??? */
287 fseek (fileref, bsz * sizeof (d10), SEEK_CUR);
288 break;
289
290 case EXE_VEC: /* entry vec */
291 if (bsz != 2) /* must be 2 wds */
292 return SCPE_FMT;
293 entvec = fxread (entbuf, sizeof (d10), bsz, fileref);
294 if (entvec < 2) /* error? */
295 return SCPE_FMT;
296 cont = 0; /* stop */
297 break;
298
299 case EXE_END: /* end */
300 if (bsz != 0) /* must be hdr */
301 return SCPE_FMT;
302 cont = 0; /* stop */
303 break;
304
305 default:
306 return SCPE_FMT;
307 } /* end switch */
308 } while (cont); /* end do */
309
310 for (i = 0; i < ndir; i = i + 2) { /* loop thru dir */
311 fpage = (int32) (dirbuf[i] & RMASK); /* file page */
312 mpage = (int32) (dirbuf[i + 1] & RMASK); /* memory page */
313 rpt = (int32) ((dirbuf[i + 1] >> 27) + 1); /* repeat count */
314 for (j = 0; j < rpt; j++, mpage++) { /* loop thru rpts */
315 if (fpage) { /* file pages? */
316 fseek (fileref, (fpage << PAG_V_PN) * sizeof (d10), SEEK_SET);
317 wc = fxread (pagbuf, sizeof (d10), PAG_SIZE, fileref);
318 if (wc < PAG_SIZE)
319 return SCPE_FMT;
320 fpage++;
321 }
322 ma = mpage << PAG_V_PN; /* mem addr */
323 for (k = 0; k < PAG_SIZE; k++, ma++) { /* copy buf to mem */
324 if (MEM_ADDR_NXM (ma))
325 return SCPE_NXM;
326 M[ma] = fpage? (pagbuf[k] & DMASK): 0;
327 } /* end copy */
328 } /* end rpt */
329 } /* end directory */
330 if (entvec && entbuf[1])
331 saved_PC = (int32) entbuf[1] & RMASK; /* start addr */
332 return SCPE_OK;
333 }
334
335 /* Master loader */
336
sim_load(FILE * fileref,char * cptr,char * fnam,int flag)337 t_stat sim_load (FILE *fileref, char *cptr, char *fnam, int flag)
338 {
339 d10 data;
340 int32 wc, fmt;
341 extern int32 sim_switches;
342
343 fmt = 0; /* no fmt */
344 if (sim_switches & SWMASK ('R')) /* -r? */
345 fmt = FMT_R;
346 else if (sim_switches & SWMASK ('S')) /* -s? */
347 fmt = FMT_S;
348 else if (sim_switches & SWMASK ('E')) /* -e? */
349 fmt = FMT_E;
350 else if (match_ext (fnam, "RIM")) /* .RIM? */
351 fmt = FMT_R;
352 else if (match_ext (fnam, "SAV")) /* .SAV? */
353 fmt = FMT_S;
354 else if (match_ext (fnam, "EXE")) /* .EXE? */
355 fmt = FMT_E;
356 else {
357 wc = fxread (&data, sizeof (d10), 1, fileref); /* read hdr */
358 if (wc == 0) /* error? */
359 return SCPE_FMT;
360 if (LRZ (data) == EXE_DIR) /* EXE magic? */
361 fmt = FMT_E;
362 else if (TSTS (data)) /* SAV magic? */
363 fmt = FMT_S;
364 fseek (fileref, 0, SEEK_SET); /* rewind */
365 }
366
367 switch (fmt) { /* case fmt */
368
369 case FMT_R: /* RIM */
370 return load_rim (fileref);
371
372 case FMT_S: /* SAV */
373 return load_sav (fileref);
374
375 case FMT_E: /* EXE */
376 return load_exe (fileref);
377 }
378
379 printf ("Can't determine load file format\n");
380 return SCPE_FMT;
381 }
382
383 /* Symbol tables */
384
385 #define I_V_FL 39 /* inst class */
386 #define I_M_FL 03 /* class mask */
387 #define I_ITS 004000000000000 /* ITS flag */
388 #define I_AC 000000000000000 /* AC, address */
389 #define I_OP 010000000000000 /* address only */
390 #define I_IO 020000000000000 /* classic I/O */
391 #define I_V_AC 00
392 #define I_V_OP 01
393 #define I_V_IO 02
394
395 static const d10 masks[] = {
396 0777000000000, 0777740000000,
397 0700340000000, 0777777777777
398 };
399
400 static const char *opcode[] = {
401 "XCTR", "XCTI", /* ITS only */
402 "IORDI", "IORDQ", "IORD", "IOWR", "IOWRI", "IOWRQ",
403 "IORDBI", "IORDBQ", "IORDB", "IOWRB", "IOWRBI", "IOWRBQ",
404 "CLRCSH", "RDPCST", "WRPCST",
405 "SDBR1", "SDBR2", "SDBR3", "SDBR4", "SPM",
406 "LDBR1", "LDBR2", "LDBR3", "LDBR4", "LPMR",
407
408 "PORTAL", "JRSTF", "HALT", /* AC defines op */
409 "XJRSTF", "XJEN", "XPCW",
410 "JEN", "SFM", "XJRST", "IBP",
411 "JFOV", "JCRY1", "JCRY0", "JCRY", "JOV",
412
413 "APRID", "WRAPR", "RDAPR", "WRPI", "RDPI", "RDUBR", "CLRPT", "WRUBR",
414 "WREBR", "RDEBR",
415 "RDSPB", "RDCSB", "RDPUR", "RDCSTM", "RDTIM", "RDINT", "RDHSB",
416 "WRSPB", "WRCSB", "WRPUR", "WRCSTM", "WRTIM", "WRINT", "WRHSB",
417
418 "LUUO01", "LUUO02", "LUUO03", "LUUO04", "LUUO05", "LUUO06", "LUUO07",
419 "LUUO10", "LUUO11", "LUUO12", "LUUO13", "LUUO14", "LUUO15", "LUUO16", "LUUO17",
420 "LUUO20", "LUUO21", "LUUO22", "LUUO23", "LUUO24", "LUUO25", "LUUO26", "LUUO27",
421 "LUUO30", "LUUO31", "LUUO32", "LUUO33", "LUUO34", "LUUO35", "LUUO36", "LUUO37",
422 "MUUO40", "MUUO41", "MUUO42", "MUUO43", "MUUO44", "MUUO45", "MUUO46", "MUUO47",
423 "MUUO50", "MUUO51", "MUUO52", "MUUO53", "MUUO54", "MUUO55", "MUUO56", "MUUO57",
424 "MUUO60", "MUUO61", "MUUO62", "MUUO63", "MUUO64", "MUUO65", "MUUO66", "MUUO67",
425 "MUUO70", "MUUO71", "MUUO72", "MUUO73", "MUUO74", "MUUO75", "MUUO76", "MUUO77",
426
427 "UJEN", "GFAD", "GFSB", "JSYS", "ADJSP", "GFMP", "GFDV ",
428 "DFAD", "DFSB", "DFMP", "DFDV", "DADD", "DSUB", "DMUL", "DDIV",
429 "DMOVE", "DMOVN", "FIX", "EXTEND", "DMOVEM", "DMOVNM", "FIXR", "FLTR",
430 "UFA", "DFN", "FSC", "ADJBP", "ILDB", "LDB", "IDPB", "DPB",
431 "FAD", "FADL", "FADM", "FADB", "FADR", "FADRL", "FADRM", "FADRB",
432 "FSB", "FSBL", "FSBM", "FSBB", "FSBR", "FSBRL", "FSBRM", "FSBRB",
433 "FMP", "FMPL", "FMPM", "FMPB", "FMPR", "FMPRL", "FMPRM", "FMPRB",
434 "FDV", "FDVL", "FDVM", "FDVB", "FDVR", "FDVRL", "FDVRM", "FDVRB",
435
436 "MOVE", "MOVEI", "MOVEM", "MOVES", "MOVS", "MOVSI", "MOVSM", "MOVSS",
437 "MOVN", "MOVNI", "MOVNM", "MOVNS", "MOVM", "MOVMI", "MOVMM", "MOVMS",
438 "IMUL", "IMULI", "IMULM", "IMULB", "MUL", "MULI", "MULM", "MULB",
439 "IDIV", "IDIVI", "IDIVM", "IDIVB", "DIV", "DIVI", "DIVM", "DIVB",
440 "ASH", "ROT", "LSH", "JFFO", "ASHC", "ROTC", "LSHC", "CIRC",
441 "EXCH", "BLT", "AOBJP", "AOBJN", "JRST", "JFCL", "XCT", "MAP",
442 "PUSHJ", "PUSH", "POP", "POPJ", "JSR", "JSP", "JSA", "JRA",
443 "ADD", "ADDI", "ADDM", "ADDB", "SUB", "SUBI", "SUBM", "SUBB",
444
445 "CAI", "CAIL", "CAIE", "CAILE", "CAIA", "CAIGE", "CAIN", "CAIG",
446 "CAM", "CAML", "CAME", "CAMLE", "CAMA", "CAMGE", "CAMN", "CAMG",
447 "JUMP", "JUMPL", "JUMPE", "JUMPLE", "JUMPA", "JUMPGE", "JUMPN", "JUMPG",
448 "SKIP", "SKIPL", "SKIPE", "SKIPLE", "SKIPA", "SKIPGE", "SKIPN", "SKIPG",
449 "AOJ", "AOJL", "AOJE", "AOJLE", "AOJA", "AOJGE", "AOJN", "AOJG",
450 "AOS", "AOSL", "AOSE", "AOSLE", "AOSA", "AOSGE", "AOSN", "AOSG",
451 "SOJ", "SOJL", "SOJE", "SOJLE", "SOJA", "SOJGE", "SOJN", "SOJG",
452 "SOS", "SOSL", "SOSE", "SOSLE", "SOSA", "SOSGE", "SOSN", "SOSG",
453
454 "SETZ", "SETZI", "SETZM", "SETZB", "AND", "ANDI", "ANDM", "ANDB",
455 "ANDCA", "ANDCAI", "ANDCAM", "ANDCAB", "SETM", "SETMI", "SETMM", "SETMB",
456 "ANDCM", "ANDCMI", "ANDCMM", "ANDCMB", "SETA", "SETAI", "SETAM", "SETAB",
457 "XOR", "XORI", "XORM", "XORB", "IOR", "IORI", "IORM", "IORB",
458 "ANDCB", "ANDCBI", "ANDCBM", "ANDCBB", "EQV", "EQVI", "EQVM", "EQVB",
459 "SETCA", "SETCAI", "SETCAM", "SETCAB", "ORCA", "ORCAI", "ORCAM", "ORCAB",
460 "SETCM", "SETCMI", "SETCMM", "SETCMB", "ORCM", "ORCMI", "ORCMM", "ORCMB",
461 "ORCB", "ORCBI", "ORCBM", "ORCBB", "SETO", "SETOI", "SETOM", "SETOB",
462
463 "HLL", "HLLI", "HLLM", "HLLS", "HRL", "HRLI", "HRLM", "HRLS",
464 "HLLZ", "HLLZI", "HLLZM", "HLLZS", "HRLZ", "HRLZI", "HRLZM", "HRLZS",
465 "HLLO", "HLLOI", "HLLOM", "HLLOS", "HRLO", "HRLOI", "HRLOM", "HRLOS",
466 "HLLE", "HLLEI", "HLLEM", "HLLES", "HRLE", "HRLEI", "HRLEM", "HRLES",
467 "HRR", "HRRI", "HRRM", "HRRS", "HLR", "HLRI", "HLRM", "HLRS",
468 "HRRZ", "HRRZI", "HRRZM", "HRRZS", "HLRZ", "HLRZI", "HLRZM", "HLRZS",
469 "HRRO", "HRROI", "HRROM", "HRROS", "HLRO", "HLROI", "HLROM", "HLROS",
470 "HRRE", "HRREI", "HRREM", "HRRES", "HLRE", "HLREI", "HLREM", "HLRES",
471
472 "TRN", "TLN", "TRNE", "TLNE", "TRNA", "TLNA", "TRNN", "TLNN",
473 "TDN", "TSN", "TDNE", "TSNE", "TDNA", "TSNA", "TDNN", "TSNN",
474 "TRZ", "TLZ", "TRZE", "TLZE", "TRZA", "TLZA", "TRZN", "TLZN",
475 "TDZ", "TSZ", "TDZE", "TSZE", "TDZA", "TSZA", "TDZN", "TSZN",
476 "TRC", "TLC", "TRCE", "TLCE", "TRCA", "TLCA", "TRCN", "TLCN",
477 "TDC", "TSC", "TDCE", "TSCE", "TDCA", "TSCA", "TDCN", "TSCN",
478 "TRO", "TLO", "TROE", "TLOE", "TROA", "TLOA", "TRON", "TLON",
479 "TDO", "TSO", "TDOE", "TSOE", "TDOA", "TSOA", "TDON", "TSON",
480
481 "UMOVE", "UMOVEM", /* KS10 I/O */
482 "TIOE", "TION", "RDIO", "WRIO",
483 "BSIO", "BCIO", "BLTBU", "BLTUB",
484 "TIOEB", "TIONB", "RDIOB", "WRIOB",
485 "BSIOB", "BCIOB",
486
487 "BLKI", "DATAI", "BLKO", "DATAO", /* classic I/O */
488 "CONO", "CONI", "CONSZ", "CONSO",
489
490 "CLEAR", "CLEARI", "CLEARM", "CLEARB",
491 "OR", "ORI", "ORM", "ORB", "XMOVEI", "XHLLI", /* alternate ops */
492
493 "CMPSL", "CMPSE", "CMPSLE", /* extended ops */
494 "EDIT", "CMPSGE", "CMPSN", "CMPSG",
495 "CVTDBO", "CVTDBT", "CVTBDO", "CVTBDT",
496 "MOVSO", "MOVST", "MOVSLJ", "MOVSRJ",
497 "XBLT", "GSNGL", "GDBLE", "GDFIX",
498 "GFIX", "GDFIXR", "GFIXR", "DGFLTR",
499 "GFLTR", "GFSC",
500
501 NULL
502 };
503
504 static const d10 opc_val[] = {
505 0102000000000+I_AC+I_ITS, 0103000000000+I_AC+I_ITS,
506 0710000000000+I_AC+I_ITS, 0711000000000+I_AC+I_ITS, 0712000000000+I_AC+I_ITS,
507 0713000000000+I_AC+I_ITS, 0714000000000+I_AC+I_ITS, 0715000000000+I_AC+I_ITS,
508 0720000000000+I_AC+I_ITS, 0721000000000+I_AC+I_ITS, 0722000000000+I_AC+I_ITS,
509 0723000000000+I_AC+I_ITS, 0724000000000+I_AC+I_ITS, 0725000000000+I_AC+I_ITS,
510 0701000000000+I_OP+I_ITS, 0701440000000+I_OP+I_ITS, 0701540000000+I_OP+I_ITS,
511 0702000000000+I_OP+I_ITS, 0702040000000+I_OP+I_ITS,
512 0702100000000+I_OP+I_ITS, 0702140000000+I_OP+I_ITS, 0702340000000+I_OP+I_ITS,
513 0702400000000+I_OP+I_ITS, 0702440000000+I_OP+I_ITS,
514 0702500000000+I_OP+I_ITS, 0702540000000+I_OP+I_ITS, 0702740000000+I_OP+I_ITS,
515
516 0254040000000+I_OP, 0254100000000+I_OP,
517 0254200000000+I_OP, 0254240000000+I_OP, 0254300000000+I_OP, 0254340000000+I_OP,
518 0254500000000+I_OP, 0254600000000+I_OP, 0254640000000+I_OP, 0133000000000+I_OP,
519 0255040000000+I_OP, 0255100000000+I_OP, 0255200000000+I_OP, 0255300000000+I_OP,
520 0255400000000+I_OP,
521
522 0700000000000+I_OP, 0700200000000+I_OP, 0700240000000+I_OP, 0700600000000+I_OP,
523 0700640000000+I_OP, 0701040000000+I_OP, 0701100000000+I_OP, 0701140000000+I_OP,
524 0701200000000+I_OP, 0701240000000+I_OP,
525 0702000000000+I_OP, 0702040000000+I_OP, 0702100000000+I_OP, 0702140000000+I_OP,
526 0702200000000+I_OP, 0702240000000+I_OP, 0702300000000+I_OP,
527 0702400000000+I_OP, 0702440000000+I_OP, 0702500000000+I_OP, 0702540000000+I_OP,
528 0702600000000+I_OP, 0702640000000+I_OP, 0702700000000+I_OP,
529
530 0001000000000+I_AC, 0002000000000+I_AC, 0003000000000+I_AC,
531 0004000000000+I_AC, 0005000000000+I_AC, 0006000000000+I_AC, 0007000000000+I_AC,
532 0010000000000+I_AC, 0011000000000+I_AC, 0012000000000+I_AC, 0013000000000+I_AC,
533 0014000000000+I_AC, 0015000000000+I_AC, 0016000000000+I_AC, 0017000000000+I_AC,
534 0020000000000+I_AC, 0021000000000+I_AC, 0022000000000+I_AC, 0023000000000+I_AC,
535 0024000000000+I_AC, 0025000000000+I_AC, 0026000000000+I_AC, 0027000000000+I_AC,
536 0030000000000+I_AC, 0031000000000+I_AC, 0032000000000+I_AC, 0033000000000+I_AC,
537 0034000000000+I_AC, 0035000000000+I_AC, 0036000000000+I_AC, 0037000000000+I_AC,
538 0040000000000+I_AC, 0041000000000+I_AC, 0042000000000+I_AC, 0043000000000+I_AC,
539 0044000000000+I_AC, 0045000000000+I_AC, 0046000000000+I_AC, 0047000000000+I_AC,
540 0050000000000+I_AC, 0051000000000+I_AC, 0052000000000+I_AC, 0053000000000+I_AC,
541 0054000000000+I_AC, 0055000000000+I_AC, 0056000000000+I_AC, 0057000000000+I_AC,
542 0060000000000+I_AC, 0061000000000+I_AC, 0062000000000+I_AC, 0063000000000+I_AC,
543 0064000000000+I_AC, 0065000000000+I_AC, 0066000000000+I_AC, 0067000000000+I_AC,
544 0070000000000+I_AC, 0071000000000+I_AC, 0072000000000+I_AC, 0073000000000+I_AC,
545 0074000000000+I_AC, 0075000000000+I_AC, 0076000000000+I_AC, 0077000000000+I_AC,
546
547 0100000000000+I_AC, 0102000000000+I_AC, 0103000000000+I_AC,
548 0104000000000+I_AC, 0105000000000+I_AC, 0106000000000+I_AC, 0107000000000+I_AC,
549 0110000000000+I_AC, 0111000000000+I_AC, 0112000000000+I_AC, 0113000000000+I_AC,
550 0114000000000+I_AC, 0115000000000+I_AC, 0116000000000+I_AC, 0117000000000+I_AC,
551 0120000000000+I_AC, 0121000000000+I_AC, 0122000000000+I_AC, 0123000000000+I_AC,
552 0124000000000+I_AC, 0125000000000+I_AC, 0126000000000+I_AC, 0127000000000+I_AC,
553 0130000000000+I_AC, 0131000000000+I_AC, 0132000000000+I_AC, 0133000000000+I_AC,
554 0134000000000+I_AC, 0135000000000+I_AC, 0136000000000+I_AC, 0137000000000+I_AC,
555 0140000000000+I_AC, 0141000000000+I_AC, 0142000000000+I_AC, 0143000000000+I_AC,
556 0144000000000+I_AC, 0145000000000+I_AC, 0146000000000+I_AC, 0147000000000+I_AC,
557 0150000000000+I_AC, 0151000000000+I_AC, 0152000000000+I_AC, 0153000000000+I_AC,
558 0154000000000+I_AC, 0155000000000+I_AC, 0156000000000+I_AC, 0157000000000+I_AC,
559 0160000000000+I_AC, 0161000000000+I_AC, 0162000000000+I_AC, 0163000000000+I_AC,
560 0164000000000+I_AC, 0165000000000+I_AC, 0166000000000+I_AC, 0167000000000+I_AC,
561 0170000000000+I_AC, 0171000000000+I_AC, 0172000000000+I_AC, 0173000000000+I_AC,
562 0174000000000+I_AC, 0175000000000+I_AC, 0176000000000+I_AC, 0177000000000+I_AC,
563
564 0200000000000+I_AC, 0201000000000+I_AC, 0202000000000+I_AC, 0203000000000+I_AC,
565 0204000000000+I_AC, 0205000000000+I_AC, 0206000000000+I_AC, 0207000000000+I_AC,
566 0210000000000+I_AC, 0211000000000+I_AC, 0212000000000+I_AC, 0213000000000+I_AC,
567 0214000000000+I_AC, 0215000000000+I_AC, 0216000000000+I_AC, 0217000000000+I_AC,
568 0220000000000+I_AC, 0221000000000+I_AC, 0222000000000+I_AC, 0223000000000+I_AC,
569 0224000000000+I_AC, 0225000000000+I_AC, 0226000000000+I_AC, 0227000000000+I_AC,
570 0230000000000+I_AC, 0231000000000+I_AC, 0232000000000+I_AC, 0233000000000+I_AC,
571 0234000000000+I_AC, 0235000000000+I_AC, 0236000000000+I_AC, 0237000000000+I_AC,
572 0240000000000+I_AC, 0241000000000+I_AC, 0242000000000+I_AC, 0243000000000+I_AC,
573 0244000000000+I_AC, 0245000000000+I_AC, 0246000000000+I_AC, 0247000000000+I_AC+I_ITS,
574 0250000000000+I_AC, 0251000000000+I_AC, 0252000000000+I_AC, 0253000000000+I_AC,
575 0254000000000+I_AC, 0255000000000+I_AC, 0256000000000+I_AC, 0257000000000+I_AC,
576 0260000000000+I_AC, 0261000000000+I_AC, 0262000000000+I_AC, 0263000000000+I_AC,
577 0264000000000+I_AC, 0265000000000+I_AC, 0266000000000+I_AC, 0267000000000+I_AC,
578 0270000000000+I_AC, 0271000000000+I_AC, 0272000000000+I_AC, 0273000000000+I_AC,
579 0274000000000+I_AC, 0275000000000+I_AC, 0276000000000+I_AC, 0277000000000+I_AC,
580
581 0300000000000+I_AC, 0301000000000+I_AC, 0302000000000+I_AC, 0303000000000+I_AC,
582 0304000000000+I_AC, 0305000000000+I_AC, 0306000000000+I_AC, 0307000000000+I_AC,
583 0310000000000+I_AC, 0311000000000+I_AC, 0312000000000+I_AC, 0313000000000+I_AC,
584 0314000000000+I_AC, 0315000000000+I_AC, 0316000000000+I_AC, 0317000000000+I_AC,
585 0320000000000+I_AC, 0321000000000+I_AC, 0322000000000+I_AC, 0323000000000+I_AC,
586 0324000000000+I_AC, 0325000000000+I_AC, 0326000000000+I_AC, 0327000000000+I_AC,
587 0330000000000+I_AC, 0331000000000+I_AC, 0332000000000+I_AC, 0333000000000+I_AC,
588 0334000000000+I_AC, 0335000000000+I_AC, 0336000000000+I_AC, 0337000000000+I_AC,
589 0340000000000+I_AC, 0341000000000+I_AC, 0342000000000+I_AC, 0343000000000+I_AC,
590 0344000000000+I_AC, 0345000000000+I_AC, 0346000000000+I_AC, 0347000000000+I_AC,
591 0350000000000+I_AC, 0351000000000+I_AC, 0352000000000+I_AC, 0353000000000+I_AC,
592 0354000000000+I_AC, 0355000000000+I_AC, 0356000000000+I_AC, 0357000000000+I_AC,
593 0360000000000+I_AC, 0361000000000+I_AC, 0362000000000+I_AC, 0363000000000+I_AC,
594 0364000000000+I_AC, 0365000000000+I_AC, 0366000000000+I_AC, 0367000000000+I_AC,
595 0370000000000+I_AC, 0371000000000+I_AC, 0372000000000+I_AC, 0373000000000+I_AC,
596 0374000000000+I_AC, 0375000000000+I_AC, 0376000000000+I_AC, 0377000000000+I_AC,
597
598 0400000000000+I_AC, 0401000000000+I_AC, 0402000000000+I_AC, 0403000000000+I_AC,
599 0404000000000+I_AC, 0405000000000+I_AC, 0406000000000+I_AC, 0407000000000+I_AC,
600 0410000000000+I_AC, 0411000000000+I_AC, 0412000000000+I_AC, 0413000000000+I_AC,
601 0414000000000+I_AC, 0415000000000+I_AC, 0416000000000+I_AC, 0417000000000+I_AC,
602 0420000000000+I_AC, 0421000000000+I_AC, 0422000000000+I_AC, 0423000000000+I_AC,
603 0424000000000+I_AC, 0425000000000+I_AC, 0426000000000+I_AC, 0427000000000+I_AC,
604 0430000000000+I_AC, 0431000000000+I_AC, 0432000000000+I_AC, 0433000000000+I_AC,
605 0434000000000+I_AC, 0435000000000+I_AC, 0436000000000+I_AC, 0437000000000+I_AC,
606 0440000000000+I_AC, 0441000000000+I_AC, 0442000000000+I_AC, 0443000000000+I_AC,
607 0444000000000+I_AC, 0445000000000+I_AC, 0446000000000+I_AC, 0447000000000+I_AC,
608 0450000000000+I_AC, 0451000000000+I_AC, 0452000000000+I_AC, 0453000000000+I_AC,
609 0454000000000+I_AC, 0455000000000+I_AC, 0456000000000+I_AC, 0457000000000+I_AC,
610 0460000000000+I_AC, 0461000000000+I_AC, 0462000000000+I_AC, 0463000000000+I_AC,
611 0464000000000+I_AC, 0465000000000+I_AC, 0466000000000+I_AC, 0467000000000+I_AC,
612 0470000000000+I_AC, 0471000000000+I_AC, 0472000000000+I_AC, 0473000000000+I_AC,
613 0474000000000+I_AC, 0475000000000+I_AC, 0476000000000+I_AC, 0477000000000+I_AC,
614
615 0500000000000+I_AC, 0501000000000+I_AC, 0502000000000+I_AC, 0503000000000+I_AC,
616 0504000000000+I_AC, 0505000000000+I_AC, 0506000000000+I_AC, 0507000000000+I_AC,
617 0510000000000+I_AC, 0511000000000+I_AC, 0512000000000+I_AC, 0513000000000+I_AC,
618 0514000000000+I_AC, 0515000000000+I_AC, 0516000000000+I_AC, 0517000000000+I_AC,
619 0520000000000+I_AC, 0521000000000+I_AC, 0522000000000+I_AC, 0523000000000+I_AC,
620 0524000000000+I_AC, 0525000000000+I_AC, 0526000000000+I_AC, 0527000000000+I_AC,
621 0530000000000+I_AC, 0531000000000+I_AC, 0532000000000+I_AC, 0533000000000+I_AC,
622 0534000000000+I_AC, 0535000000000+I_AC, 0536000000000+I_AC, 0537000000000+I_AC,
623 0540000000000+I_AC, 0541000000000+I_AC, 0542000000000+I_AC, 0543000000000+I_AC,
624 0544000000000+I_AC, 0545000000000+I_AC, 0546000000000+I_AC, 0547000000000+I_AC,
625 0550000000000+I_AC, 0551000000000+I_AC, 0552000000000+I_AC, 0553000000000+I_AC,
626 0554000000000+I_AC, 0555000000000+I_AC, 0556000000000+I_AC, 0557000000000+I_AC,
627 0560000000000+I_AC, 0561000000000+I_AC, 0562000000000+I_AC, 0563000000000+I_AC,
628 0564000000000+I_AC, 0565000000000+I_AC, 0566000000000+I_AC, 0567000000000+I_AC,
629 0570000000000+I_AC, 0571000000000+I_AC, 0572000000000+I_AC, 0573000000000+I_AC,
630 0574000000000+I_AC, 0575000000000+I_AC, 0576000000000+I_AC, 0577000000000+I_AC,
631
632 0600000000000+I_AC, 0601000000000+I_AC, 0602000000000+I_AC, 0603000000000+I_AC,
633 0604000000000+I_AC, 0605000000000+I_AC, 0606000000000+I_AC, 0607000000000+I_AC,
634 0610000000000+I_AC, 0611000000000+I_AC, 0612000000000+I_AC, 0613000000000+I_AC,
635 0614000000000+I_AC, 0615000000000+I_AC, 0616000000000+I_AC, 0617000000000+I_AC,
636 0620000000000+I_AC, 0621000000000+I_AC, 0622000000000+I_AC, 0623000000000+I_AC,
637 0624000000000+I_AC, 0625000000000+I_AC, 0626000000000+I_AC, 0627000000000+I_AC,
638 0630000000000+I_AC, 0631000000000+I_AC, 0632000000000+I_AC, 0633000000000+I_AC,
639 0634000000000+I_AC, 0635000000000+I_AC, 0636000000000+I_AC, 0637000000000+I_AC,
640 0640000000000+I_AC, 0641000000000+I_AC, 0642000000000+I_AC, 0643000000000+I_AC,
641 0644000000000+I_AC, 0645000000000+I_AC, 0646000000000+I_AC, 0647000000000+I_AC,
642 0650000000000+I_AC, 0651000000000+I_AC, 0652000000000+I_AC, 0653000000000+I_AC,
643 0654000000000+I_AC, 0655000000000+I_AC, 0656000000000+I_AC, 0657000000000+I_AC,
644 0660000000000+I_AC, 0661000000000+I_AC, 0662000000000+I_AC, 0663000000000+I_AC,
645 0664000000000+I_AC, 0665000000000+I_AC, 0666000000000+I_AC, 0667000000000+I_AC,
646 0670000000000+I_AC, 0671000000000+I_AC, 0672000000000+I_AC, 0673000000000+I_AC,
647 0674000000000+I_AC, 0675000000000+I_AC, 0676000000000+I_AC, 0677000000000+I_AC,
648
649 0704000000000+I_AC, 0705000000000+I_AC,
650 0710000000000+I_AC, 0711000000000+I_AC, 0712000000000+I_AC, 0713000000000+I_AC,
651 0714000000000+I_AC, 0715000000000+I_AC, 0716000000000+I_AC, 0717000000000+I_AC,
652 0720000000000+I_AC, 0721000000000+I_AC, 0722000000000+I_AC, 0723000000000+I_AC,
653 0724000000000+I_AC, 0725000000000+I_AC,
654
655 0700000000000+I_IO, 0700040000000+I_IO, 0700100000000+I_IO, 0700140000000+I_IO,
656 0700200000000+I_IO, 0700240000000+I_IO, 0700300000000+I_IO, 0700340000000+I_IO,
657
658 0400000000000+I_AC, 0401000000000+I_AC, 0402000000000+I_AC, 0403000000000+I_AC,
659 0434000000000+I_AC, 0435000000000+I_AC, 0436000000000+I_AC, 0437000000000+I_AC,
660 0415000000000+I_AC, 0501000000000+I_AC,
661
662 0001000000000+I_AC, 0002000000000+I_AC, 0003000000000+I_AC,
663 0004000000000+I_AC, 0005000000000+I_AC, 0006000000000+I_AC, 0007000000000+I_AC,
664 0010000000000+I_AC, 0011000000000+I_AC, 0012000000000+I_AC, 0013000000000+I_AC,
665 0014000000000+I_AC, 0015000000000+I_AC, 0016000000000+I_AC, 0017000000000+I_AC,
666 0020000000000+I_AC, 0021000000000+I_AC, 0022000000000+I_AC, 0023000000000+I_AC,
667 0024000000000+I_AC, 0025000000000+I_AC, 0026000000000+I_AC, 0027000000000+I_AC,
668 0030000000000+I_AC, 0031000000000+I_AC,
669 -1
670 };
671
672 #define NUMDEV 6
673
674 static const char *devnam[NUMDEV] = {
675 "APR", "PI", "PAG", "CCA", "TIM", "MTR"
676 };
677
678 /* Symbolic decode
679
680 Inputs:
681 *of = output stream
682 addr = current PC
683 *val = pointer to values
684 *uptr = pointer to unit
685 sw = switches
686 Outputs:
687 return = status code
688 */
689
690 #define FMTASC(x) ((x) < 040)? "<%03o>": "%c", (x)
691 #define SIXTOASC(x) ((x) + 040)
692
fprint_sym(FILE * of,t_addr addr,t_value * val,UNIT * uptr,int32 sw)693 t_stat fprint_sym (FILE *of, t_addr addr, t_value *val,
694 UNIT *uptr, int32 sw)
695 {
696 int32 i, j, c, cflag, ac, xr, y, dev;
697 d10 inst;
698
699 inst = val[0];
700 cflag = (uptr == NULL) || (uptr == &cpu_unit);
701 if (sw & SWMASK ('A')) { /* ASCII? */
702 if (inst > 0377)
703 return SCPE_ARG;
704 fprintf (of, FMTASC ((int32) (inst & 0177)));
705 return SCPE_OK;
706 }
707 if (sw & SWMASK ('C')) { /* character? */
708 for (i = 30; i >= 0; i = i - 6) {
709 c = (int32) ((inst >> i) & 077);
710 fprintf (of, "%c", SIXTOASC (c));
711 }
712 return SCPE_OK;
713 }
714 if (sw & SWMASK ('P')) { /* packed? */
715 for (i = 29; i >= 0; i = i - 7) {
716 c = (int32) ((inst >> i) & 0177);
717 fprintf (of, FMTASC (c));
718 }
719 return SCPE_OK;
720 }
721 if (!(sw & SWMASK ('M')))
722 return SCPE_ARG;
723
724 /* Instruction decode */
725
726 ac = GET_AC (inst);
727 xr = GET_XR (inst);
728 y = GET_ADDR (inst);
729 dev = GET_DEV (inst);
730 for (i = 0; opc_val[i] >= 0; i++) { /* loop thru ops */
731 j = (int32) ((opc_val[i] >> I_V_FL) & I_M_FL); /* get class */
732 if (((opc_val[i] & DMASK) == (inst & masks[j])) && /* match? */
733 (((opc_val[i] & I_ITS) == 0) || Q_ITS)) {
734 fprintf (of, "%s ", opcode[i]); /* opcode */
735 switch (j) { /* case on class */
736
737 case I_V_AC: /* AC + address */
738 fprintf (of, "%-o,", ac); /* print AC, fall thru */
739 case I_V_OP: /* address only */
740 if (inst & INST_IND)
741 fprintf (of, "@");
742 if (xr)
743 fprintf (of, "%-o(%-o)", y, xr);
744 else fprintf (of, "%-o", y);
745 break;
746
747 case I_V_IO: /* I/O */
748 if (dev < NUMDEV)
749 fprintf (of, "%s,", devnam[dev]);
750 else fprintf (of, "%-o,", dev);
751 if (inst & INST_IND)
752 fprintf (of, "@");
753 if (xr)
754 fprintf (of, "%-o(%-o)", y, xr);
755 else fprintf (of, "%-o", y);
756 break;
757 } /* end case */
758 return SCPE_OK;
759 } /* end if */
760 } /* end for */
761 return SCPE_ARG;
762 }
763
764 /* Get operand, including indirect and index
765
766 Inputs:
767 *cptr = pointer to input string
768 *status = pointer to error status
769 Outputs:
770 val = output value
771 */
772
get_opnd(char * cptr,t_stat * status)773 t_value get_opnd (char *cptr, t_stat *status)
774 {
775 int32 sign = 0;
776 t_value val, xr = 0, ind = 0;
777 char *tptr;
778
779 *status = SCPE_ARG; /* assume fail */
780 if (*cptr == '@') {
781 ind = INST_IND;
782 cptr++;
783 }
784 if (*cptr == '+')
785 cptr++;
786 else if (*cptr == '-') {
787 sign = 1;
788 cptr++;
789 }
790 val = strtotv (cptr, &tptr, 8);
791 if (val > 0777777)
792 return 0;
793 if (sign)
794 val = (~val + 1) & 0777777;
795 cptr = tptr;
796 if (*cptr == '(') {
797 cptr++;
798 xr = strtotv (cptr, &tptr, 8);
799 if ((cptr == tptr) || (*tptr != ')') ||
800 (xr > AC_NUM) || (xr == 0))
801 return 0;
802 cptr = ++tptr;
803 }
804 if (*cptr == 0)
805 *status = SCPE_OK;
806 return (ind | (xr << 18) | val);
807 }
808
809 /* Symbolic input
810
811 Inputs:
812 *cptr = pointer to input string
813 addr = current PC
814 uptr = pointer to unit
815 *val = pointer to output values
816 sw = switches
817 Outputs:
818 status = error status
819 */
820
parse_sym(char * cptr,t_addr addr,UNIT * uptr,t_value * val,int32 sw)821 t_stat parse_sym (char *cptr, t_addr addr, UNIT *uptr, t_value *val, int32 sw)
822 {
823 int32 cflag, i, j;
824 t_value ac, dev;
825 t_stat r;
826 char gbuf[CBUFSIZE];
827
828 cflag = (uptr == NULL) || (uptr == &cpu_unit);
829 while (isspace (*cptr)) cptr++;
830 for (i = 0; i < 6; i++) {
831 if (cptr[i] == 0) {
832 for (j = i + 1; j <= 6; j++) cptr[j] = 0;
833 break;
834 }
835 }
836 if ((sw & SWMASK ('A')) || ((*cptr == '\'') && cptr++)) { /* ASCII char? */
837 if (cptr[0] == 0) /* must have 1 char */
838 return SCPE_ARG;
839 val[0] = (t_value) cptr[0];
840 return SCPE_OK;
841 }
842 if ((sw & SWMASK ('C')) || ((*cptr == '"') && cptr++)) { /* sixbit string? */
843 if (cptr[0] == 0) /* must have 1 char */
844 return SCPE_ARG;
845 for (i = 0; i < 6; i++) {
846 val[0] = (val[0] << 6);
847 if (cptr[i]) val[0] = val[0] |
848 ((t_value) ((cptr[i] + 040) & 077));
849 }
850 return SCPE_OK;
851 }
852 if ((sw & SWMASK ('P')) || ((*cptr == '#') && cptr++)) { /* packed string? */
853 if (cptr[0] == 0) /* must have 1 char */
854 return SCPE_ARG;
855 for (i = 0; i < 5; i++)
856 val[0] = (val[0] << 7) | ((t_value) cptr[i]);
857 val[0] = val[0] << 1;
858 return SCPE_OK;
859 }
860
861 /* Instruction parse */
862
863 cptr = get_glyph (cptr, gbuf, 0); /* get opcode */
864 for (i = 0; (opcode[i] != NULL) && (strcmp (opcode[i], gbuf) != 0) ; i++) ;
865 if (opcode[i] == NULL)
866 return SCPE_ARG;
867 val[0] = opc_val[i] & DMASK; /* get value */
868 j = (int32) ((opc_val[i] >> I_V_FL) & I_M_FL); /* get class */
869 switch (j) { /* case on class */
870
871 case I_V_AC: /* AC + operand */
872 if (strchr (cptr, ',')) { /* AC specified? */
873 cptr = get_glyph (cptr, gbuf, ','); /* get glyph */
874 if (gbuf[0]) { /* can be omitted */
875 ac = get_uint (gbuf, 8, AC_NUM - 1, &r);
876 if (r != SCPE_OK)
877 return SCPE_ARG;
878 val[0] = val[0] | (ac << INST_V_AC);
879 }
880 } /* fall through */
881 case I_V_OP: /* operand */
882 cptr = get_glyph (cptr, gbuf, 0);
883 val[0] = val[0] | get_opnd (gbuf, &r);
884 if (r != SCPE_OK)
885 return SCPE_ARG;
886 break;
887
888 case I_V_IO: /* I/O */
889 cptr = get_glyph (cptr, gbuf, ','); /* get glyph */
890 for (dev = 0; (dev < NUMDEV) && (strcmp (devnam[dev], gbuf) != 0); dev++);
891 if (dev >= NUMDEV) {
892 dev = get_uint (gbuf, 8, INST_M_DEV, &r);
893 if (r != SCPE_OK)
894 return SCPE_ARG;
895 }
896 val[0] = val[0] | (dev << INST_V_DEV);
897 cptr = get_glyph (cptr, gbuf, 0);
898 val[0] = val[0] | get_opnd (gbuf, &r);
899 if (r != SCPE_OK)
900 return SCPE_ARG;
901 break;
902 } /* end case */
903
904 if (*cptr != 0) /* junk at end? */
905 return SCPE_ARG;
906 return SCPE_OK;
907 }
908