First Commit of my working state
[simh.git] / Interdata / id16_sys.c
CommitLineData
196ba1fc
PH
1/* id16_sys.c: Interdata 16b simulator interface\r
2\r
3 Copyright (c) 2000-2008, Robert M. Supnik\r
4\r
5 Permission is hereby granted, free of charge, to any person obtaining a\r
6 copy of this software and associated documentation files (the "Software"),\r
7 to deal in the Software without restriction, including without limitation\r
8 the rights to use, copy, modify, merge, publish, distribute, sublicense,\r
9 and/or sell copies of the Software, and to permit persons to whom the\r
10 Software is furnished to do so, subject to the following conditions:\r
11\r
12 The above copyright notice and this permission notice shall be included in\r
13 all copies or substantial portions of the Software.\r
14\r
15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\r
18 ROBERT M SUPNIK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\r
19 IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
20 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
21\r
22 Except as contained in this notice, the name of Robert M Supnik shall not be\r
23 used in advertising or otherwise to promote the sale, use or other dealings\r
24 in this Software without prior written authorization from Robert M Supnik.\r
25\r
26 04-Feb-08 RMS Modified to allow -A, -B use with 8b devices\r
27 18-Oct-06 RMS Re-ordered device list\r
28 26-Mar-04 RMS Fixed warning with -std=c99\r
29 27-Feb-03 RMS Added relative addressing support\r
30*/\r
31\r
32#include "id_defs.h"\r
33#include <ctype.h>\r
34\r
35#define MSK_SBF 0x0100\r
36\r
37extern DEVICE cpu_dev;\r
38extern DEVICE sch_dev;\r
39extern DEVICE pt_dev;\r
40extern DEVICE tt_dev, ttp_dev;\r
41extern DEVICE pas_dev, pasl_dev;\r
42extern DEVICE lpt_dev;\r
43extern DEVICE pic_dev, lfc_dev;\r
44extern DEVICE dp_dev, idc_dev;\r
45extern DEVICE fd_dev, mt_dev;\r
46extern UNIT cpu_unit;\r
47extern REG cpu_reg[];\r
48extern uint16 *M;\r
49\r
50t_stat fprint_sym_m (FILE *of, t_addr addr, t_value *val);\r
51t_stat parse_sym_m (char *cptr, t_addr addr, t_value *val);\r
52extern t_stat lp_load (FILE *fileref, char *cptr, char *fnam);\r
53extern t_stat pt_dump (FILE *of, char *cptr, char *fnam);\r
54\r
55/* SCP data structures and interface routines\r
56\r
57 sim_name simulator name string\r
58 sim_PC pointer to saved PC register descriptor\r
59 sim_emax number of words for examine\r
60 sim_devices array of pointers to simulated devices\r
61 sim_stop_messages array of pointers to stop messages\r
62 sim_load binary loader\r
63*/\r
64\r
65char sim_name[] = "Interdata 16b";\r
66\r
67REG *sim_PC = &cpu_reg[0];\r
68\r
69int32 sim_emax = 2;\r
70\r
71DEVICE *sim_devices[] = {\r
72 &cpu_dev,\r
73 &sch_dev,\r
74 &pic_dev,\r
75 &lfc_dev,\r
76 &pt_dev,\r
77 &tt_dev,\r
78 &ttp_dev,\r
79 &pas_dev,\r
80 &pasl_dev,\r
81 &lpt_dev,\r
82 &dp_dev,\r
83 &idc_dev,\r
84 &fd_dev,\r
85 &mt_dev,\r
86 NULL\r
87 };\r
88\r
89const char *sim_stop_messages[] = {\r
90 "Unknown error",\r
91 "Reserved instruction",\r
92 "HALT instruction",\r
93 "Breakpoint",\r
94 "Wait state",\r
95 "Runaway VFU"\r
96 };\r
97\r
98/* Binary loader -- load carriage control tape\r
99 Binary dump -- paper tape dump */\r
100\r
101t_stat sim_load (FILE *fileref, char *cptr, char *fnam, int flag)\r
102{\r
103if (flag) return pt_dump (fileref, cptr, fnam);\r
104return lp_load (fileref, cptr, fnam);\r
105}\r
106\r
107/* Symbol tables */\r
108\r
109#define I_V_FL 16 /* class bits */\r
110#define I_M_FL 0xF /* class mask */\r
111#define I_V_MR 0x0 /* mask-register */\r
112#define I_V_RR 0x1 /* register-register */\r
113#define I_V_R 0x2 /* register */\r
114#define I_V_MX 0x3 /* mask-memory */\r
115#define I_V_RX 0x4 /* register-memory */\r
116#define I_V_X 0x5 /* memory */\r
117#define I_V_FF 0x6 /* float reg-reg */\r
118#define I_V_FX 0x7 /* float reg-mem */\r
119#define I_V_SI 0x8 /* short immed */\r
120#define I_V_SB 0x9 /* short branch */\r
121#define I_V_SX 0xA /* short ext branch */\r
122#define I_MR (I_V_MR << I_V_FL)\r
123#define I_RR (I_V_RR << I_V_FL)\r
124#define I_R (I_V_R << I_V_FL)\r
125#define I_MX (I_V_MX << I_V_FL)\r
126#define I_RX (I_V_RX << I_V_FL)\r
127#define I_X (I_V_X << I_V_FL)\r
128#define I_FF (I_V_FF << I_V_FL)\r
129#define I_FX (I_V_FX << I_V_FL)\r
130#define I_SI (I_V_SI << I_V_FL)\r
131#define I_SB (I_V_SB << I_V_FL)\r
132#define I_SX (I_V_SX << I_V_FL)\r
133\r
134#define R_X 0 /* no reg */\r
135#define R_M 1 /* reg mask */\r
136#define R_R 2 /* reg int reg */\r
137#define R_F 3 /* reg flt reg */\r
138\r
139static const int32 masks[] = {\r
140 0xFF00, 0xFF00, 0xFFF0, 0xFF00,\r
141 0xFF00, 0xFFF0, 0xFF00, 0xFF00,\r
142 0xFF00, 0xFE00, 0xFEF0\r
143 };\r
144\r
145static const uint32 r1_type[] = {\r
146 R_M, R_R, R_X, R_M,\r
147 R_R, R_X, R_F, R_F,\r
148 R_R, R_M, R_X\r
149 };\r
150\r
151static const uint32 r2_type[] = {\r
152 R_X, R_R, R_R, R_X,\r
153 R_X, R_X, R_F, R_X,\r
154 R_M, R_X, R_X\r
155 };\r
156\r
157static const char *opcode[] = {\r
158"BER", "BNER","BZR", "BNZR",\r
159"BPR", "BNPR","BLR", "BNLR",\r
160"BMR", "BNMR","BOR", "BNOR",\r
161"BCR", "BNCR","BR",\r
162"BES", "BNES","BZS", "BNZS",\r
163"BPS", "BNPS","BLS", "BNLS",\r
164"BMS", "BNMS","BOS", "BNOS",\r
165"BCS", "BNCS","BS",\r
166"BE", "BNE", "BZ", "BNZ",\r
167"BP", "BNP", "BL", "BNL",\r
168"BM", "BNM", "BO", "BNO",\r
169"BC", "BNC", "B",\r
170 "BALR","BTCR","BFCR",\r
171"NHR", "CLHR","OHR", "XHR",\r
172"LHR", "CHR", "AHR", "SHR",\r
173"MHR", "DHR", "ACHR","SCHR",\r
174 "SETMR",\r
175"BTBS","BTFS","BFBS","BFFS",\r
176"LIS", "LCS", "AIS", "SIS",\r
177"LER", "CER", "AER", "SER",\r
178"MER", "DER", "FXR", "FLR",\r
179 "LPSR",\r
180"LDR", "CDR", "ADR", "SDR",\r
181"MDR", "DDR", "FXDR","FLDR",\r
182"STH", "BAL", "BTC", "BFC",\r
183"NH", "CLH", "OH", "XH",\r
184"LH", "CH", "AH", "SH",\r
185"MH", "DH", "ACH", "SCH",\r
186 "SETM",\r
187"STE", "AHM",\r
188"ATL", "ABL", "RTL", "RBL",\r
189"LE", "CE", "AE", "SE",\r
190"ME", "DE",\r
191"STD", "STME","LME", "LPS",\r
192"LD", "CD", "AD", "SD",\r
193"MD", "DD", "STMD","LMD",\r
194"SRLS","SLLS","STBR","LBR",\r
195"EXBR","EPSR","WBR", "RBR",\r
196"WHR", "RHR", "WDR", "RDR",\r
197"MHUR","SSR", "OCR", "AIR",\r
198"BXH", "BXLE","LPSW","THI",\r
199"NHI", "CLHI","OHI", "XHI",\r
200"LHI", "CHI", "AHI", "SHI",\r
201"SRHL","SLHL","SRHA","SLHA",\r
202"STM", "LM", "STB", "LB",\r
203"CLB", "AL", "WB", "RB",\r
204"WH", "RH", "WD", "RD",\r
205"MHU", "SS", "OC", "AI",\r
206 "SVC", "SINT",\r
207 "RRL", "RLL",\r
208"SRL", "SLL", "SRA", "SLA",\r
209NULL\r
210};\r
211\r
212static const uint32 opc_val[] = {\r
2130x0330+I_R, 0x0230+I_R, 0x0330+I_R, 0x0230+I_R,\r
2140x0220+I_R, 0x0320+I_R, 0x0280+I_R, 0x0380+I_R,\r
2150x0210+I_R, 0x0310+I_R, 0x0240+I_R, 0x0340+I_R,\r
2160x0280+I_R, 0x0380+I_R, 0x0300+I_R,\r
2170x2230+I_SX, 0x2030+I_SX, 0x2230+I_SX, 0x2030+I_SX,\r
2180x2020+I_SX, 0x2220+I_SX, 0x2080+I_SX, 0x2280+I_SX,\r
2190x2010+I_SX, 0x2210+I_SX, 0x2040+I_SX, 0x2240+I_SX,\r
2200x2080+I_SX, 0x2280+I_SX, 0x2200+I_SX,\r
2210x4330+I_X, 0x4230+I_X, 0x4330+I_X, 0x4230+I_X,\r
2220x4220+I_X, 0x4320+I_X, 0x4280+I_X, 0x4380+I_X,\r
2230x4210+I_X, 0x4310+I_X, 0x4240+I_X, 0x4340+I_X,\r
2240x4280+I_X, 0x4380+I_X, 0x4300+I_X,\r
225 0x0100+I_RR, 0x0200+I_MR, 0x0300+I_MR,\r
2260x0400+I_RR, 0x0500+I_RR, 0x0600+I_RR, 0x0700+I_RR,\r
2270x0800+I_RR, 0x0900+I_RR, 0x0A00+I_RR, 0x0B00+I_RR,\r
2280x0C00+I_RR, 0x0D00+I_RR, 0x0E00+I_RR, 0x0F00+I_RR,\r
229 0x1300+I_RR,\r
2300x2000+I_SB, 0x2100+I_SB, 0x2200+I_SB, 0x2300+I_SB,\r
2310x2400+I_SI, 0x2500+I_SI, 0x2600+I_SI, 0x2700+I_SI,\r
2320x2800+I_FF, 0x2900+I_FF, 0x2A00+I_FF, 0x2B00+I_FF,\r
2330x2C00+I_FF, 0x2D00+I_FF, 0x2E00+I_RR, 0x2F00+I_RR,\r
234 0x3300+I_R,\r
2350x3800+I_FF, 0x3900+I_FF, 0x3A00+I_FF, 0x3B00+I_FF,\r
2360x3C00+I_FF, 0x3D00+I_FF, 0x3E00+I_RR, 0x3F00+I_RR,\r
2370x4000+I_RX, 0x4100+I_RX, 0x4200+I_MX, 0x4300+I_MX,\r
2380x4400+I_RX, 0x4500+I_RX, 0x4600+I_RX, 0x4700+I_RX,\r
2390x4800+I_RX, 0x4900+I_RX, 0x4A00+I_RX, 0x4B00+I_RX,\r
2400x4C00+I_RX, 0x4D00+I_RX, 0x4E00+I_RX, 0x4F00+I_RX,\r
241 0x5300+I_RX,\r
2420x6000+I_RX, 0x6100+I_RX,\r
2430x6400+I_RX, 0x6500+I_RX, 0x6600+I_RX, 0x6700+I_RX,\r
2440x6800+I_FX, 0x6900+I_FX, 0x6A00+I_FX, 0x6B00+I_FX,\r
2450x6C00+I_FX, 0x6D00+I_FX,\r
2460x7000+I_FX, 0x7100+I_FX, 0x7200+I_FX, 0x7300+I_X,\r
2470x7800+I_FX, 0x7900+I_FX, 0x7A00+I_FX, 0x7B00+I_FX,\r
2480x7C00+I_FX, 0x7D00+I_FX, 0x7E00+I_FX, 0x7F00+I_FX,\r
2490x9000+I_SI, 0x9100+I_SI, 0x9200+I_RR, 0x9300+I_RR,\r
2500x9400+I_RR, 0x9500+I_RR, 0x9600+I_RR, 0x9700+I_RR,\r
2510x9800+I_RR, 0x9900+I_RR, 0x9A00+I_RR, 0x9B00+I_RR,\r
2520x9C00+I_RR, 0x9D00+I_RR, 0x9E00+I_RR, 0x9F00+I_RR,\r
2530xC000+I_RX, 0xC100+I_RX, 0xC200+I_X, 0xC300+I_RX,\r
2540xC400+I_RX, 0xC500+I_RX, 0xC600+I_RX, 0xC700+I_RX,\r
2550xC800+I_RX, 0xC900+I_RX, 0xCA00+I_RX, 0xCB00+I_RX,\r
2560xCC00+I_RX, 0xCD00+I_RX, 0xCE00+I_RX, 0xCF00+I_RX,\r
2570xD000+I_RX, 0xD100+I_RX, 0xD200+I_RX, 0xD300+I_RX,\r
2580xD400+I_RX, 0xD500+I_X, 0xD600+I_RX, 0xD700+I_RX,\r
2590xD800+I_RX, 0xD900+I_RX, 0xDA00+I_RX, 0xDB00+I_RX,\r
2600xDC00+I_RX, 0xDD00+I_RX, 0xDE00+I_RX, 0xDF00+I_RX,\r
261 0xE100+I_RX, 0xE200+I_RX,\r
262 0xEA00+I_RX, 0xEB00+I_RX,\r
2630xEC00+I_RX, 0xED00+I_RX, 0xEE00+I_RX, 0xEF00+I_RX,\r
2640xFFFF\r
265};\r
266\r
267/* Symbolic decode\r
268\r
269 Inputs:\r
270 *of = output stream\r
271 addr = current PC\r
272 *val = values to decode\r
273 *uptr = pointer to unit\r
274 sw = switches\r
275 Outputs:\r
276 return = if >= 0, error code\r
277 if < 0, number of extra bytes retired\r
278*/\r
279\r
280t_stat fprint_sym (FILE *of, t_addr addr, t_value *val,\r
281 UNIT *uptr, int32 sw)\r
282{\r
283int32 bflag, c1, c2, rdx;\r
284t_stat r;\r
285DEVICE *dptr;\r
286\r
287if (uptr == NULL) uptr = &cpu_unit; /* anon = CPU */\r
288dptr = find_dev_from_unit (uptr); /* find dev */\r
289if (dptr == NULL) return SCPE_IERR;\r
290if (dptr->dwidth < 16) bflag = 1; /* 8b dev? */\r
291else bflag = 0; /* assume 16b */\r
292if (sw & SWMASK ('D')) rdx = 10; /* get radix */\r
293else if (sw & SWMASK ('O')) rdx = 8;\r
294else if (sw & SWMASK ('H')) rdx = 16;\r
295else rdx = dptr->dradix;\r
296\r
297if (sw & SWMASK ('A')) { /* ASCII char? */\r
298 if (bflag) c1 = val[0] & 0x7F;\r
299 else c1 = (val[0] >> ((addr & 1)? 0: 8)) & 0x7F; /* get byte */\r
300 fprintf (of, (c1 < 0x20)? "<%02X>": "%c", c1);\r
301 return 0;\r
302 }\r
303if (sw & SWMASK ('B')) { /* byte? */\r
304 if (bflag) c1 = val[0] & 0xFF;\r
305 else c1 = (val[0] >> ((addr & 1)? 0: 8)) & 0xFF; /* get byte */\r
306 fprint_val (of, c1, rdx, 8, PV_RZRO);\r
307 return 0;\r
308 }\r
309if (bflag) return SCPE_ARG; /* 16b only */\r
310\r
311if (sw & SWMASK ('C')) { /* string? */\r
312 c1 = (val[0] >> 8) & 0x7F;\r
313 c2 = val[0] & 0x7F;\r
314 fprintf (of, (c1 < 0x20)? "<%02X>": "%c", c1);\r
315 fprintf (of, (c2 < 0x20)? "<%02X>": "%c", c2);\r
316 return -1;\r
317 }\r
318if (sw & SWMASK ('F')) { /* fullword? */\r
319 fprint_val (of, (val[0] << 16) | val[1], rdx, 32, PV_RZRO);\r
320 return -3;\r
321 }\r
322if (sw & SWMASK ('M')) { /* inst format? */\r
323 r = fprint_sym_m (of, addr, val); /* decode inst */\r
324 if (r <= 0) return r;\r
325 }\r
326\r
327fprint_val (of, val[0], rdx, 16, PV_RZRO);\r
328return -1;\r
329}\r
330\r
331/* Symbolic decode for -m\r
332\r
333 Inputs:\r
334 of = output stream\r
335 addr = current PC\r
336 *val = values to decode\r
337 Outputs:\r
338 return = if >= 0, error code\r
339 if < 0, number of extra bytes retired\r
340*/\r
341\r
342t_stat fprint_sym_m (FILE *of, t_addr addr, t_value *val)\r
343{\r
344uint32 i, j, inst, r1, r2, ea, vp;\r
345\r
346vp = 0;\r
347inst = val[0]; /* first 16b */\r
348ea = val[1]; /* second 16b */\r
349for (i = 0; opcode[i] != NULL; i++) { /* loop thru ops */\r
350 j = (opc_val[i] >> I_V_FL) & I_M_FL; /* get class */\r
351 if ((opc_val[i] & 0xFFFF) == (inst & masks[j])) { /* match? */\r
352 r1 = (inst >> 4) & 0xF;\r
353 r2 = inst & 0xF;\r
354 fprintf (of, "%s ", opcode[i]); /* print opcode */\r
355 switch (j) { /* case on class */\r
356\r
357 case I_V_MR: /* mask-register */\r
358 fprintf (of, "%-X,R%d", r1, r2);\r
359 return -1;\r
360\r
361 case I_V_RR: /* register-register */\r
362 case I_V_FF: /* floating-floating */\r
363 fprintf (of, "R%d,R%d", r1, r2);\r
364 return -1;\r
365\r
366 case I_V_SI: /* short immediate */\r
367 fprintf (of, "R%d,%-X", r1, r2);\r
368 return -1;\r
369\r
370 case I_V_SB: /* short branch */\r
371 fprintf (of, "%-X,", r1);\r
372 case I_V_SX: /* ext short branch */\r
373 fprintf (of, "%-X", ((inst & MSK_SBF)?\r
374 (addr + r2 + r2): (addr - r2 - r2)));\r
375 return -1;\r
376\r
377 case I_V_R: /* register */\r
378 fprintf (of, "R%d", r2);\r
379 return -1;\r
380\r
381 case I_V_MX: /* mask-memory */\r
382 fprintf (of, "%-X,%-X", r1, ea);\r
383 break;\r
384\r
385 case I_V_RX: /* register-memory */\r
386 case I_V_FX: /* floating-memory */\r
387 fprintf (of, "R%d,%-X", r1, ea);\r
388 break;\r
389\r
390 case I_V_X: /* memory */\r
391 fprintf (of, "%-X", ea);\r
392 break;\r
393 } /* end case */\r
394\r
395 if (r2) fprintf (of, "(R%d)", r2); \r
396 return -3;\r
397 } /* end if */\r
398 } /* end for */\r
399return SCPE_ARG; /* no match */\r
400}\r
401\r
402/* Register number\r
403\r
404 Inputs:\r
405 *cptr = pointer to input string\r
406 **optr = pointer to pointer to next char\r
407 rtype = mask, integer, or float\r
408 Outputs:\r
409 rnum = output register number, -1 if error\r
410*/\r
411\r
412int32 get_reg (char *cptr, char **optr, int32 rtype)\r
413{\r
414int32 reg;\r
415\r
416if ((*cptr == 'R') || (*cptr == 'r')) { /* R? */\r
417 cptr++; /* skip */\r
418 if (rtype == R_M) return -1; /* cant be mask */\r
419 }\r
420if ((*cptr >= '0') && (*cptr <= '9')) {\r
421 reg = *cptr++ - '0';\r
422 if ((*cptr >= '0') && (*cptr <= '9'))\r
423 reg = (reg * 10) + (*cptr - '0'); \r
424 else --cptr;\r
425 if (reg > 0xF) return -1;\r
426 }\r
427else if ((*cptr >= 'a') && (*cptr <= 'f')) reg = (*cptr - 'a') + 10;\r
428else if ((*cptr >= 'A') && (*cptr <= 'F')) reg = (*cptr - 'A') + 10;\r
429else return -1;\r
430if ((rtype == R_F) && (reg & 1)) return -1;\r
431*optr = cptr + 1;\r
432return reg;\r
433}\r
434\r
435/* Address\r
436\r
437 Inputs:\r
438 *cptr = pointer to input string\r
439 **tptr = pointer to moved pointer\r
440 *ea = effective address\r
441 addr = base address\r
442 Outputs:\r
443 status = SCPE_OK if ok, else error code\r
444*/\r
445\r
446t_stat get_addr (char *cptr, char **tptr, t_addr *ea, t_addr addr)\r
447{\r
448int32 sign = 1;\r
449\r
450if (*cptr == '.') { /* relative? */\r
451 cptr++;\r
452 *ea = addr;\r
453 if (*cptr == '+') cptr++; /* .+? */\r
454 else if (*cptr == '-') { /* .-? */\r
455 sign = -1;\r
456 cptr++;\r
457 }\r
458 else return SCPE_OK;\r
459 }\r
460else *ea = 0;\r
461errno = 0;\r
462*ea = *ea + (sign * ((int32) strtoul (cptr, tptr, 16)));\r
463if (errno || (cptr == *tptr)) return SCPE_ARG;\r
464return SCPE_OK;\r
465}\r
466\r
467/* Symbolic input */\r
468\r
469t_stat parse_sym (char *cptr, t_addr addr, UNIT *uptr, t_value *val, int32 sw)\r
470{\r
471int32 bflag, by, rdx, num;\r
472t_stat r;\r
473DEVICE *dptr;\r
474\r
475if (uptr == NULL) uptr = &cpu_unit; /* anon = CPU */\r
476dptr = find_dev_from_unit (uptr); /* find dev */\r
477if (dptr == NULL) return SCPE_IERR;\r
478if (dptr->dwidth < 16) bflag = 1; /* 8b device? */\r
479else bflag = 0; /* assume 16b */\r
480if (sw & SWMASK ('D')) rdx = 10; /* get radix */\r
481else if (sw & SWMASK ('O')) rdx = 8;\r
482else if (sw & SWMASK ('H')) rdx = 16;\r
483else rdx = dptr->dradix;\r
484\r
485if ((sw & SWMASK ('A')) || ((*cptr == '\'') && cptr++)) { /* ASCII char? */\r
486 if (cptr[0] == 0) return SCPE_ARG; /* must have 1 char */\r
487 if (bflag) val[0] = (t_value) cptr[0];\r
488 else val[0] = (addr & 1)?\r
489 (val[0] & ~0xFF) | ((t_value) cptr[0]):\r
490 (val[0] & 0xFF) | (((t_value) cptr[0]) << 8);\r
491 return 0;\r
492 }\r
493if (sw & SWMASK ('B')) { /* byte? */\r
494 by = get_uint (cptr, rdx, DMASK8, &r); /* get byte */\r
495 if (r != SCPE_OK) return SCPE_ARG;\r
496 if (bflag) val[0] = by;\r
497 else val[0] = (addr & 1)?\r
498 (val[0] & ~0xFF) | by:\r
499 (val[0] & 0xFF) | (by << 8);\r
500 return 0;\r
501 }\r
502if (bflag) return SCPE_ARG; /* 16b only */\r
503\r
504if ((sw & SWMASK ('C')) || ((*cptr == '"') && cptr++)) { /* ASCII chars? */\r
505 if (cptr[0] == 0) return SCPE_ARG; /* must have 1 char */\r
506 val[0] = ((t_value) cptr[0] << 8) | (t_value) cptr[1];\r
507 return -1;\r
508 }\r
509if (sw & SWMASK ('F')) {\r
510 num = (int32) get_uint (cptr, rdx, DMASK32, &r); /* get number */\r
511 if (r != SCPE_OK) return r;\r
512 val[0] = (num >> 16) & DMASK16;\r
513 val[1] = num & DMASK16;\r
514 return -3;\r
515 }\r
516\r
517r = parse_sym_m (cptr, addr, val); /* try to parse inst */\r
518if (r <= 0) return r;\r
519val[0] = (int32) get_uint (cptr, rdx, DMASK16, &r); /* get number */\r
520if (r != SCPE_OK) return r;\r
521return -1;\r
522}\r
523\r
524/* Symbolic input for -m\r
525\r
526 Inputs:\r
527 *cptr = pointer to input string\r
528 addr = current PC\r
529 *val = pointer to output values\r
530 cf = true if parsing for CPU\r
531 Outputs:\r
532 status = > 0 error code\r
533 <= 0 -number of extra words\r
534*/\r
535\r
536t_stat parse_sym_m (char *cptr, t_addr addr, t_value *val)\r
537{\r
538uint32 i, j, t, df, db, inst;\r
539int32 st, r1, r2;\r
540t_stat r;\r
541char *tptr, gbuf[CBUFSIZE];\r
542\r
543cptr = get_glyph (cptr, gbuf, 0); /* get opcode */\r
544for (i = 0; (opcode[i] != NULL) && (strcmp (opcode[i], gbuf) != 0) ; i++) ;\r
545if (opcode[i] == NULL) return SCPE_ARG;\r
546inst = opc_val[i] & 0xFFFF; /* get value */\r
547j = (opc_val[i] >> I_V_FL) & I_M_FL; /* get class */\r
548if (r1_type[j]) { /* any R1 field? */\r
549 cptr = get_glyph (cptr, gbuf, ','); /* get R1 field */\r
550 if ((r1 = get_reg (gbuf, &tptr, r1_type[j])) < 0)\r
551 return SCPE_ARG;\r
552 if (*tptr != 0) return SCPE_ARG; /* all done? */\r
553 inst = inst | (r1 << 4); /* or in R1 */\r
554 }\r
555\r
556cptr = get_glyph (cptr, gbuf, 0); /* get operand */\r
557if (*cptr) return SCPE_ARG; /* should be end */\r
558switch (j) { /* case on class */\r
559\r
560 case I_V_FF: case I_V_SI: /* flt-flt, sh imm */\r
561 case I_V_MR: case I_V_RR: /* mask/reg-reg */\r
562 case I_V_R: /* register */\r
563 if ((r2 = get_reg (gbuf, &tptr, r2_type[j])) < 0)\r
564 return SCPE_ARG;\r
565 if (*tptr != 0) return SCPE_ARG; /* all done? */\r
566 inst = inst | r2; /* or in R2 */\r
567 break;\r
568\r
569 case I_V_FX: /* float-memory */\r
570 case I_V_MX: case I_V_RX: /* mask/reg-mem */\r
571 case I_V_X: /* memory */\r
572 r = get_addr (gbuf, &tptr, &t, addr); /* get addr */\r
573 if ((r != SCPE_OK) || (t > PAMASK16)) return SCPE_ARG;\r
574 if (*tptr == '(') { /* index? */\r
575 if ((r2 = get_reg (tptr + 1, &tptr, R_R)) < 0)\r
576 return SCPE_ARG;\r
577 if (*tptr++ != ')') return SCPE_ARG;\r
578 inst = inst | r2; /* or in R2 */\r
579 }\r
580 if (*tptr != 0) return SCPE_ARG;\r
581 val[0] = inst;\r
582 val[1] = t;\r
583 return -3;\r
584\r
585 case I_V_SB: case I_V_SX: /* short branches */\r
586 r = get_addr (gbuf, &tptr, &t, addr); /* get addr */\r
587 if ((r != SCPE_OK) || (t & 1) || *tptr) /* error if odd */\r
588 return SCPE_ARG;\r
589 st = t; /* signed version */\r
590 db = (addr - t) & 0x1F; /* back displ */\r
591 df = (t - addr) & 0x1F; /* fwd displ */\r
592 if ((t == ((addr - db) & VAMASK16)) && /* back work and */\r
593 ((j == I_V_SX) || !(inst & MSK_SBF))) /* ext or back br? */\r
594 inst = inst | (db >> 1); /* or in back displ */\r
595 else if ((t == ((addr + df) & VAMASK16)) && /* fwd work and */\r
596 ((j == I_V_SX) || (inst & MSK_SBF))) /* ext or fwd br? */\r
597 inst = inst | (df >> 1) | MSK_SBF; /* or in fwd displ */\r
598 else return SCPE_ARG;\r
599 break;\r
600 } /* end case */\r
601\r
602val[0] = inst;\r
603return -1;\r
604}\r