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