This source file includes following definitions.
- parseval
- getval
- name_match
- back_cable_iom_to_scu
- cable_scu_to_iom
- back_cable_cpu_to_scu
- cable_scu_to_cpu
- cable_scu
- cable_ctlr_to_iom
- cable_ctlr
- cable_iom
- cable_periph_to_ctlr
- cable_periph
- cable_mtp
- cable_ipc
- cable_msp
- cable_urp
- sys_cable
- cable_init
- sys_cable_graph
- sys_cable_show
- sys_cable_ripout
- sysCableInit
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114 #include <ctype.h>
115
116 #include "dps8.h"
117 #include "dps8_simh.h"
118 #include "dps8_iom.h"
119 #include "dps8_mt.h"
120 #include "dps8_socket_dev.h"
121 #include "dps8_sys.h"
122 #include "dps8_cable.h"
123 #include "dps8_cpu.h"
124 #include "dps8_faults.h"
125 #include "dps8_scu.h"
126 #include "dps8_state.h"
127 #include "dps8_console.h"
128 #include "dps8_disk.h"
129 #include "dps8_fnp2.h"
130 #include "dps8_urp.h"
131 #include "dps8_crdrdr.h"
132 #include "dps8_crdpun.h"
133 #include "dps8_prt.h"
134 #include "dps8_utils.h"
135 #if !defined(__MINGW64__) && !defined(__MINGW32__) && !defined (CROSS_MINGW64) && !defined (CROSS_MINGW32)
136 # include "dps8_absi.h"
137 #endif
138 #include "dps8_mgp.h"
139 #include "dps8_net.h"
140 #if defined(M_SHARED)
141 # include <unistd.h>
142 # include "shm.h"
143 #endif
144
145 #define DBG_CTR 1
146
147 #if defined(FREE)
148 # undef FREE
149 #endif
150 #define FREE(p) do \
151 { \
152 free((p)); \
153 (p) = NULL; \
154 } while(0)
155
156 struct cables_s * cables = NULL;
157
158 char * ctlr_type_strs [] =
159 {
160 "none",
161 "MTP", "MSP", "IPC", "OPC",
162 "URP", "FNP", "ABSI", "SKC", "MGP", "NET"
163 };
164
165 char * chan_type_strs [] =
166 {
167 "CPI", "PSI", "Direct"
168 };
169
170 static t_stat sys_cable_graph (void);
171
172 static int parseval (char * value)
173 {
174 if (! value)
175 return -1;
176 if (strlen (value) == 1 && value[0] >= 'a' && value[0] <= 'z')
177 return (int) (value[0] - 'a');
178 if (strlen (value) == 1 && value[0] >= 'A' && value[0] <= 'Z')
179 return (int) (value[0] - 'A');
180 char * endptr;
181 long l = strtol (value, & endptr, 0);
182 if (* endptr || l < 0 || l > INT_MAX)
183 {
184 sim_printf ("error: CABLE: can't parse %s\r\n", value);
185 return -1;
186 }
187 return (int) l;
188 }
189
190 static int getval (char * * save, char * text)
191 {
192 char * value;
193 value = strtok_r (NULL, ", ", save);
194 if (! value)
195 {
196 sim_printf ("error: CABLE: can't parse %s\r\n", text);
197 return -1;
198 }
199 return parseval (value);
200 }
201
202
203
204
205
206
207 static bool name_match (const char * str, const char * pattern, uint * val)
208 {
209
210 size_t pat_len = strlen (pattern);
211 if (strncasecmp (pattern, str, pat_len))
212 return false;
213
214
215 size_t rest = strlen (str) - pat_len;
216 const char * p = str + pat_len;
217
218
219 if (! rest)
220 return false;
221
222
223 char * q;
224 char * tags = "abcdefghijklmnopqrstuvwxyz";
225 if (rest == 1 && (q = strchr (tags, tolower (*p))))
226 {
227 * val = (uint) (q - tags);
228 return true;
229 }
230
231
232 char * digits = "0123456789";
233 q = strchr (digits, tolower (*p));
234 if (! q)
235 return false;
236
237 long l = strtol (p, & q, 0);
238 if (* q || l < 0 || l > INT_MAX)
239 {
240 sim_printf ("error: sys_cable: can't parse %s\r\n", str);
241 return false;
242 }
243 * val = (uint) l;
244 return true;
245 }
246
247
248
249 static t_stat back_cable_iom_to_scu (int uncable, uint iom_unit_idx, uint iom_port_num, uint scu_unit_idx, uint scu_port_num)
250 {
251 struct iom_to_scu_s * p = & cables->iom_to_scu[iom_unit_idx][iom_port_num];
252 if (uncable)
253 {
254 p->in_use = false;
255 }
256 else
257 {
258 if (p->in_use)
259 {
260 sim_printf ("cable SCU: IOM%u port %u in use.\r\n", iom_unit_idx, iom_port_num);
261 return SCPE_ARG;
262 }
263 p->in_use = true;
264 p->scu_unit_idx = scu_unit_idx;
265 p->scu_port_num = scu_port_num;
266 }
267 return SCPE_OK;
268 }
269
270
271
272 static t_stat cable_scu_to_iom (int uncable, uint scu_unit_idx, uint scu_port_num, uint iom_unit_idx, uint iom_port_num)
273 {
274 struct scu_to_iom_s * p = & cables->scu_to_iom[scu_unit_idx][scu_port_num];
275 if (uncable)
276 {
277 if (! p->in_use)
278 {
279 sim_printf ("uncable SCU%u port %d: not cabled\r\n", scu_unit_idx, scu_port_num);
280 return SCPE_ARG;
281 }
282
283
284 t_stat rc = back_cable_iom_to_scu (uncable, iom_unit_idx, iom_port_num,
285 scu_unit_idx, scu_port_num);
286 if (rc)
287 {
288 return rc;
289 }
290
291 p->in_use = false;
292 scu[scu_unit_idx].ports[scu_port_num].type = ADEV_NONE;
293 scu[scu_unit_idx].ports[scu_port_num].dev_idx = 0;
294
295 scu[scu_unit_idx].ports[scu_port_num].is_exp = false;
296
297 }
298 else
299 {
300 if (p->in_use)
301 {
302 sim_printf ("cable_scu: SCU %d port %d in use.\r\n", scu_unit_idx, scu_port_num);
303 return SCPE_ARG;
304 }
305
306
307 t_stat rc = back_cable_iom_to_scu (uncable, iom_unit_idx, iom_port_num,
308 scu_unit_idx, scu_port_num);
309 if (rc)
310 {
311 return rc;
312 }
313
314 p->in_use = true;
315 p->iom_unit_idx = iom_unit_idx;
316 p->iom_port_num = (uint) iom_port_num;
317
318 scu[scu_unit_idx].ports[scu_port_num].type = ADEV_IOM;
319 scu[scu_unit_idx].ports[scu_port_num].dev_idx = (int) iom_unit_idx;
320 scu[scu_unit_idx].ports[scu_port_num].dev_port[0] = (int) iom_port_num;
321
322 scu[scu_unit_idx].ports[scu_port_num].is_exp = 0;
323
324 }
325 return SCPE_OK;
326 }
327
328
329
330 static t_stat back_cable_cpu_to_scu (int uncable, uint cpu_unit_idx, uint cpu_port_num,
331 uint scu_unit_idx, uint scu_port_num, uint scu_subport_num)
332 {
333 struct cpu_to_scu_s * p = & cables->cpu_to_scu[cpu_unit_idx][cpu_port_num];
334 if (uncable)
335 {
336 p->in_use = false;
337 }
338 else
339 {
340 if (p->in_use)
341 {
342 sim_printf ("cable SCU: CPU%u port %u in use.\r\n", cpu_unit_idx, cpu_port_num);
343 return SCPE_ARG;
344 }
345 p->in_use = true;
346 p->scu_unit_idx = scu_unit_idx;
347 p->scu_port_num = scu_port_num;
348 p->scu_subport_num = scu_subport_num;
349 }
350 return SCPE_OK;
351 }
352
353
354
355 static t_stat cable_scu_to_cpu (int uncable, uint scu_unit_idx, uint scu_port_num,
356 uint scu_subport_num, uint cpu_unit_idx, uint cpu_port_num, bool is_exp)
357 {
358 struct scu_to_cpu_s * p = & cables->scu_to_cpu[scu_unit_idx][scu_port_num][scu_subport_num];
359 if (uncable)
360 {
361 if (! p->in_use)
362 {
363 sim_printf ("uncable SCU%u port %u subport %u: not cabled\r\n",
364 scu_unit_idx, scu_port_num, scu_subport_num);
365 return SCPE_ARG;
366 }
367
368
369 t_stat rc = back_cable_cpu_to_scu (uncable, cpu_unit_idx, cpu_port_num,
370 scu_unit_idx, scu_port_num, scu_subport_num);
371 if (rc)
372 {
373 return rc;
374 }
375
376 p->in_use = false;
377 scu[scu_unit_idx].ports[scu_port_num].type = ADEV_NONE;
378 scu[scu_unit_idx].ports[scu_port_num].dev_idx = 0;
379
380 scu[scu_unit_idx].ports[scu_port_num].is_exp = false;
381 scu[scu_unit_idx].ports[scu_port_num].dev_port[scu_subport_num] = 0;
382 }
383 else
384 {
385 if (p->in_use)
386 {
387 sim_printf ("cable_scu: SCU %u port %u subport %u in use.\r\n",
388 scu_unit_idx, scu_port_num, scu_subport_num);
389 return SCPE_ARG;
390 }
391
392
393 t_stat rc = back_cable_cpu_to_scu (uncable, cpu_unit_idx, cpu_port_num,
394 scu_unit_idx, scu_port_num, scu_subport_num);
395 if (rc)
396 {
397 return rc;
398 }
399
400 p->in_use = true;
401 p->cpu_unit_idx = cpu_unit_idx;
402 p->cpu_port_num = (uint) cpu_port_num;
403
404 scu[scu_unit_idx].ports[scu_port_num].type = ADEV_CPU;
405 scu[scu_unit_idx].ports[scu_port_num].dev_idx = (int) cpu_unit_idx;
406 scu[scu_unit_idx].ports[scu_port_num].dev_port[0] = (int) cpu_port_num;
407
408 scu[scu_unit_idx].ports[scu_port_num].is_exp = is_exp;
409 scu[scu_unit_idx].ports[scu_port_num].dev_port[scu_subport_num] = (int) cpu_port_num;
410
411 cpus[cpu_unit_idx].scu_port[scu_unit_idx] = scu_port_num;
412 }
413
414 setup_scbank_map (_cpup);
415 return SCPE_OK;
416 }
417
418
419
420
421 static t_stat cable_scu (int uncable, uint scu_unit_idx, char * * name_save)
422 {
423 if (scu_unit_idx >= scu_dev.numunits)
424 {
425 sim_printf ("cable_scu: SCU unit number out of range <%d>\r\n",
426 scu_unit_idx);
427 return SCPE_ARG;
428 }
429
430 int scu_port_num = getval (name_save, "SCU port number");
431
432
433
434
435
436
437
438
439
440
441
442
443
444 char * param = strtok_r (NULL, ", ", name_save);
445 if (! param)
446 {
447 sim_printf ("cable_scu: can't parse IOM\r\n");
448 return SCPE_ARG;
449 }
450 uint unit_idx;
451
452
453 if (name_match (param, "IOM", & unit_idx))
454 {
455 if (unit_idx >= N_IOM_UNITS_MAX)
456 {
457 sim_printf ("cable SCU: IOM unit number out of range <%d>\r\n", unit_idx);
458 return SCPE_ARG;
459 }
460
461 if (scu_port_num < 0 || scu_port_num >= N_SCU_PORTS)
462 {
463 sim_printf ("cable_scu: SCU port number out of range <%d>\r\n",
464 scu_port_num);
465 return SCPE_ARG;
466 }
467
468
469 param = strtok_r (NULL, ", ", name_save);
470 if (! param)
471 {
472 sim_printf ("cable SCU: can't parse IOM port number\r\n");
473 return SCPE_ARG;
474 }
475 int iom_port_num = parseval (param);
476
477 if (iom_port_num < 0 || iom_port_num >= N_IOM_PORTS)
478 {
479 sim_printf ("cable SCU: IOM port number out of range <%d>\r\n", iom_port_num);
480 return SCPE_ARG;
481 }
482 return cable_scu_to_iom (uncable, scu_unit_idx, (uint) scu_port_num,
483 unit_idx, (uint) iom_port_num);
484 }
485
486
487 else if (name_match (param, "CPU", & unit_idx))
488 {
489 if (unit_idx >= N_CPU_UNITS_MAX)
490 {
491 sim_printf ("cable SCU: IOM unit number out of range <%d>\r\n", unit_idx);
492 return SCPE_ARG;
493 }
494
495
496
497
498
499
500
501
502
503 int scu_subport_num = 0;
504 bool is_exp = false;
505 int exp_port = scu_port_num / 10;
506 if (exp_port)
507 {
508 scu_subport_num = scu_port_num % 10;
509 if (scu_subport_num < 0 || scu_subport_num >= N_SCU_SUBPORTS)
510 {
511 sim_printf ("cable SCU: subport number out of range <%d>\r\n",
512 scu_subport_num);
513 return SCPE_ARG;
514 }
515 scu_port_num /= 10;
516 is_exp = true;
517 }
518 if (scu_port_num < 0 || scu_port_num >= N_SCU_PORTS)
519 {
520 sim_printf ("cable SCU: port number out of range <%d>\r\n",
521 scu_port_num);
522 return SCPE_ARG;
523 }
524
525
526 param = strtok_r (NULL, ", ", name_save);
527 if (! param)
528 {
529 sim_printf ("cable SCU: can't parse CPU port number\r\n");
530 return SCPE_ARG;
531 }
532 int cpu_port_num = parseval (param);
533
534 if (cpu_port_num < 0 || cpu_port_num >= N_CPU_PORTS)
535 {
536 sim_printf ("cable SCU: CPU port number out of range <%d>\r\n", cpu_port_num);
537 return SCPE_ARG;
538 }
539 return cable_scu_to_cpu (uncable, scu_unit_idx, (uint) scu_port_num,
540 (uint) scu_subport_num, unit_idx, (uint) cpu_port_num, is_exp);
541 }
542 else
543 {
544 sim_printf ("cable SCU: can't parse IOM or CPU\r\n");
545 return SCPE_ARG;
546 }
547 }
548
549 static t_stat cable_ctlr_to_iom (int uncable, struct ctlr_to_iom_s * there,
550 uint iom_unit_idx, uint chan_num)
551 {
552 if (uncable)
553 {
554 if (! there->in_use)
555 {
556 sim_printf ("error: UNCABLE: controller not cabled\r\n");
557 return SCPE_ARG;
558 }
559 if (there->iom_unit_idx != iom_unit_idx ||
560 there->chan_num != chan_num)
561 {
562 sim_printf ("error: UNCABLE: wrong controller\r\n");
563 return SCPE_ARG;
564 }
565 there->in_use = false;
566 }
567 else
568 {
569 if (there->in_use)
570 {
571 sim_printf ("error: CABLE: controller in use\r\n");
572 return SCPE_ARG;
573 }
574 there->in_use = true;
575 there->iom_unit_idx = iom_unit_idx;
576 there->chan_num = chan_num;
577 }
578 return SCPE_OK;
579 }
580
581 static t_stat cable_ctlr (int uncable,
582 uint iom_unit_idx, uint chan_num,
583 uint ctlr_unit_idx, uint port_num,
584 char * service,
585 DEVICE * devp,
586 struct ctlr_to_iom_s * there,
587 enum ctlr_type_e ctlr_type, enum chan_type_e chan_type,
588 UNIT * unitp, iom_cmd_t * iom_cmd)
589 {
590 if (ctlr_unit_idx >= devp->numunits)
591 {
592 sim_printf ("%s: unit index out of range <%d>\r\n",
593 service, ctlr_unit_idx);
594 return SCPE_ARG;
595 }
596
597 struct iom_to_ctlr_s * p = & cables->iom_to_ctlr[iom_unit_idx][chan_num];
598
599 if (uncable)
600 {
601 if (! p->in_use)
602 {
603 sim_printf ("%s: not cabled\r\n", service);
604 return SCPE_ARG;
605 }
606
607 if (p->ctlr_unit_idx != ctlr_unit_idx)
608 {
609 sim_printf ("%s: Wrong IOM expected %d, found %d\r\n",
610 service, ctlr_unit_idx, p->ctlr_unit_idx);
611 return SCPE_ARG;
612 }
613
614
615 t_stat rc = cable_ctlr_to_iom (uncable, there,
616 iom_unit_idx, chan_num);
617 if (rc)
618 {
619 return rc;
620 }
621 p->in_use = false;
622 p->iom_cmd = NULL;
623 }
624 else
625 {
626 if (p->in_use)
627 {
628 sim_printf ("%s: socket in use; unit number %d. (%o); "
629 "not cabling.\r\n", service, iom_unit_idx, iom_unit_idx);
630 return SCPE_ARG;
631 }
632
633
634 t_stat rc = cable_ctlr_to_iom (uncable, there,
635 iom_unit_idx, chan_num);
636 if (rc)
637 {
638 return rc;
639 }
640 p->in_use = true;
641 p->ctlr_unit_idx = ctlr_unit_idx;
642 p->port_num = port_num;
643 p->ctlr_type = ctlr_type;
644 p->chan_type = chan_type;
645 p->dev = devp;
646 p->board = unitp;
647 p->iom_cmd = iom_cmd;
648 }
649
650 return SCPE_OK;
651 }
652
653
654
655
656
657
658
659
660
661
662
663 static t_stat cable_iom (int uncable, uint iom_unit_idx, char * * name_save)
664 {
665 if (iom_unit_idx >= iom_dev.numunits)
666 {
667 sim_printf ("error: CABLE IOM: unit number out of range <%d>\r\n",
668 iom_unit_idx);
669 return SCPE_ARG;
670 }
671
672 int chan_num = getval (name_save, "IOM channel number");
673
674 if (chan_num < 0 || chan_num >= MAX_CHANNELS)
675 {
676 sim_printf ("error: CABLE IOM channel number out of range <%d>\r\n",
677 chan_num);
678 return SCPE_ARG;
679 }
680
681
682 char * param = strtok_r (NULL, ", ", name_save);
683 if (! param)
684 {
685 sim_printf ("error: CABLE IOM can't parse controller type\r\n");
686 return SCPE_ARG;
687 }
688 uint unit_idx;
689
690
691 if (name_match (param, "IPC", & unit_idx))
692 {
693 if (unit_idx >= N_IPC_UNITS_MAX)
694 {
695 sim_printf ("error: CABLE IOM: IPC unit number out of range <%d>\r\n", unit_idx);
696 return SCPE_ARG;
697 }
698
699
700 int ipc_port_num = 0;
701 param = strtok_r (NULL, ", ", name_save);
702 if (param)
703 ipc_port_num = parseval (param);
704
705 if (ipc_port_num < 0 || ipc_port_num >= MAX_CTLR_PORTS)
706 {
707 sim_printf ("error: CABLE IOM: IPC port number out of range <%d>\r\n", ipc_port_num);
708 return SCPE_ARG;
709 }
710 return cable_ctlr (uncable,
711 iom_unit_idx, (uint) chan_num,
712 unit_idx, (uint) ipc_port_num,
713 "CABLE IOMx IPCx",
714 & ipc_dev,
715 & cables->ipc_to_iom[unit_idx][ipc_port_num],
716 CTLR_T_IPC, chan_type_PSI,
717 & ipc_unit [unit_idx], dsk_iom_cmd);
718 }
719
720
721 if (name_match (param, "MSP", & unit_idx))
722 {
723 if (unit_idx >= N_MSP_UNITS_MAX)
724 {
725 sim_printf ("error: CABLE IOM: MSP unit number out of range <%d>\r\n", unit_idx);
726 return SCPE_ARG;
727 }
728
729
730 int msp_port_num = 0;
731 param = strtok_r (NULL, ", ", name_save);
732 if (param)
733 msp_port_num = parseval (param);
734
735 if (msp_port_num < 0 || msp_port_num >= MAX_CTLR_PORTS)
736 {
737 sim_printf ("error: CABLE IOM: MSP port number out of range <%d>\r\n", msp_port_num);
738 return SCPE_ARG;
739 }
740 return cable_ctlr (uncable,
741 iom_unit_idx, (uint) chan_num,
742 unit_idx, (uint) msp_port_num,
743 "CABLE IOMx MSPx",
744 & msp_dev,
745 & cables->msp_to_iom[unit_idx][msp_port_num],
746 CTLR_T_MSP, chan_type_PSI,
747 & msp_unit [unit_idx], dsk_iom_cmd);
748 }
749
750
751 if (name_match (param, "MTP", & unit_idx))
752 {
753 if (unit_idx >= N_MTP_UNITS_MAX)
754 {
755 sim_printf ("error: CABLE IOM: MTP unit number out of range <%d>\r\n", unit_idx);
756 return SCPE_ARG;
757 }
758
759
760 int mtp_port_num = 0;
761 param = strtok_r (NULL, ", ", name_save);
762 if (param)
763 mtp_port_num = parseval (param);
764
765 if (mtp_port_num < 0 || mtp_port_num >= MAX_CTLR_PORTS)
766 {
767 sim_printf ("error: CABLE IOM: MTP port number out of range <%d>\r\n", mtp_port_num);
768 return SCPE_ARG;
769 }
770 return cable_ctlr (uncable,
771 iom_unit_idx, (uint) chan_num,
772 unit_idx, (uint) mtp_port_num,
773 "CABLE IOMx MTPx",
774 & mtp_dev,
775 & cables->mtp_to_iom[unit_idx][mtp_port_num],
776 CTLR_T_MTP, chan_type_PSI,
777 & mtp_unit [unit_idx], mt_iom_cmd);
778 }
779
780
781 if (name_match (param, "URP", & unit_idx))
782 {
783 if (unit_idx >= N_URP_UNITS_MAX)
784 {
785 sim_printf ("error: CABLE IOM: URP unit number out of range <%d>\r\n", unit_idx);
786 return SCPE_ARG;
787 }
788
789
790 int urp_port_num = 0;
791 param = strtok_r (NULL, ", ", name_save);
792 if (param)
793 urp_port_num = parseval (param);
794
795 if (urp_port_num < 0 || urp_port_num >= MAX_CTLR_PORTS)
796 {
797 sim_printf ("error: CABLE IOM: URP port number out of range <%d>\r\n", urp_port_num);
798 return SCPE_ARG;
799 }
800
801 return cable_ctlr (uncable,
802 iom_unit_idx, (uint) chan_num,
803 unit_idx, (uint) urp_port_num,
804 "CABLE IOMx URPx",
805 & urp_dev,
806 & cables->urp_to_iom[unit_idx][urp_port_num],
807 CTLR_T_URP, chan_type_PSI,
808 & urp_unit [unit_idx], urp_iom_cmd);
809 }
810
811
812 if (name_match (param, "OPC", & unit_idx))
813 {
814 if (unit_idx >= N_OPC_UNITS_MAX)
815 {
816 sim_printf ("error: CABLE IOM: OPC unit number out of range <%d>\r\n", unit_idx);
817 return SCPE_ARG;
818 }
819
820 uint opc_port_num = 0;
821 return cable_ctlr (uncable,
822 iom_unit_idx, (uint) chan_num,
823 unit_idx, opc_port_num,
824 "CABLE IOMx OPCx",
825 & opc_dev,
826 & cables->opc_to_iom[unit_idx][opc_port_num],
827 CTLR_T_OPC, chan_type_CPI,
828 & opc_unit [unit_idx], opc_iom_cmd);
829 }
830
831
832 if (name_match (param, "FNP", & unit_idx))
833 {
834 if (unit_idx >= N_FNP_UNITS_MAX)
835 {
836 sim_printf ("error: CABLE IOM: FNP unit number out of range <%d>\r\n", unit_idx);
837 return SCPE_ARG;
838 }
839
840 uint fnp_port_num = 0;
841 return cable_ctlr (uncable,
842 iom_unit_idx, (uint) chan_num,
843 unit_idx, fnp_port_num,
844 "CABLE IOMx FNPx",
845 & fnp_dev,
846 & cables->fnp_to_iom[unit_idx][fnp_port_num],
847 CTLR_T_FNP, chan_type_direct,
848 & fnp_unit [unit_idx], fnp_iom_cmd);
849 }
850
851 #if defined(WITH_ABSI_DEV)
852 # if !defined(__MINGW64__) && !defined(__MINGW32__) && !defined (CROSS_MINGW64) && !defined(CROSS_MINGW32)
853
854 if (name_match (param, "ABSI", & unit_idx))
855 {
856 if (unit_idx >= N_ABSI_UNITS_MAX)
857 {
858 sim_printf ("error: CABLE IOM: ABSI unit number out of range <%d>\r\n", unit_idx);
859 return SCPE_ARG;
860 }
861
862 uint absi_port_num = 0;
863 return cable_ctlr (uncable,
864 iom_unit_idx, (uint) chan_num,
865 unit_idx, absi_port_num,
866 "CABLE IOMx ABSIx",
867 & absi_dev,
868 & cables->absi_to_iom[unit_idx][absi_port_num],
869 CTLR_T_ABSI, chan_type_direct,
870 & absi_unit [unit_idx], absi_iom_cmd);
871 }
872 # endif
873 #endif
874
875 #if defined(WITH_MGP_DEV)
876
877 if (name_match (param, "MGP", & unit_idx))
878 {
879 if (unit_idx >= N_MGP_UNITS_MAX)
880 {
881 sim_printf ("error: CABLE IOM: MGP unit number out of range <%d>\r\n", unit_idx);
882 return SCPE_ARG;
883 }
884
885 uint mgp_port_num = 0;
886 return cable_ctlr (uncable,
887 iom_unit_idx, (uint) chan_num,
888 unit_idx, mgp_port_num,
889 "CABLE IOMx MGPx",
890 & mgp_dev,
891 & cables->mgp_to_iom[unit_idx][mgp_port_num],
892 CTLR_T_MGP, chan_type_direct,
893 & mgp_unit [unit_idx], mgp_iom_cmd);
894 }
895 #endif
896
897 #if defined(WITH_NET_DEV)
898
899 if (name_match (param, "NET", & unit_idx))
900 {
901 if (unit_idx >= N_NET_UNITS_MAX)
902 {
903 sim_printf ("error: CABLE IOM: NET unit number out of range <%d>\r\n", unit_idx);
904 return SCPE_ARG;
905 }
906
907 uint net_port_num = 0;
908 return cable_ctlr (uncable,
909 iom_unit_idx, (uint) chan_num,
910 unit_idx, net_port_num,
911 "CABLE IOMx NETx",
912 & net_dev,
913 & cables->net_to_iom[unit_idx][net_port_num],
914 CTLR_T_NET, chan_type_direct,
915 & net_unit [unit_idx], net_iom_cmd);
916 }
917 #endif
918
919 #if defined(WITH_SOCKET_DEV)
920 # if !defined(__MINGW64__) && !defined(__MINGW32__) && !defined(CROSS_MINGW64) && !defined(CROSS_MINGW32)
921
922 if (name_match (param, "SKC", & unit_idx))
923 {
924 if (unit_idx >= N_SKC_UNITS_MAX)
925 {
926 sim_printf ("error: CABLE IOM: SKC unit number out of range <%d>\r\n", unit_idx);
927 return SCPE_ARG;
928 }
929
930 uint skc_port_num = 0;
931 return cable_ctlr (uncable,
932 iom_unit_idx, (uint) chan_num,
933 unit_idx, skc_port_num,
934 "CABLE IOMx SKCx",
935 & skc_dev,
936 & cables->sk_to_iom[unit_idx][skc_port_num],
937 CTLR_T_SKC, chan_type_direct,
938 & sk_unit [unit_idx], skc_iom_cmd);
939 }
940 # endif
941 #endif
942
943 sim_printf ("cable IOM: can't parse controller type\r\n");
944 return SCPE_ARG;
945 }
946
947 static t_stat cable_periph_to_ctlr (int uncable,
948 uint ctlr_unit_idx, uint dev_code,
949 enum ctlr_type_e ctlr_type,
950 struct dev_to_ctlr_s * there,
951 UNUSED iom_cmd_t * iom_cmd)
952 {
953 if (uncable)
954 {
955 if (! there->in_use)
956 {
957 sim_printf ("error: UNCABLE: device not cabled\r\n");
958 return SCPE_ARG;
959 }
960 if (there->ctlr_unit_idx != ctlr_unit_idx ||
961 there->dev_code != dev_code)
962 {
963 sim_printf ("error: UNCABLE: wrong controller\r\n");
964 return SCPE_ARG;
965 }
966 there->in_use = false;
967 }
968 else
969 {
970 if (there->in_use)
971 {
972 sim_printf ("error: CABLE: device in use\r\n");
973 return SCPE_ARG;
974 }
975 there->in_use = true;
976 there->ctlr_unit_idx = ctlr_unit_idx;
977 there->dev_code = dev_code;
978 there->ctlr_type = ctlr_type;
979 }
980 return SCPE_OK;
981 }
982
983 static t_stat cable_periph (int uncable,
984 uint ctlr_unit_idx,
985 uint dev_code,
986 enum ctlr_type_e ctlr_type,
987 struct ctlr_to_dev_s * here,
988 uint unit_idx,
989 iom_cmd_t * iom_cmd,
990 struct dev_to_ctlr_s * there,
991 char * service)
992 {
993 if (uncable)
994 {
995 if (! here->in_use)
996 {
997 sim_printf ("%s: socket not in use\r\n", service);
998 return SCPE_ARG;
999 }
1000
1001 t_stat rc = cable_periph_to_ctlr (uncable,
1002 ctlr_unit_idx, dev_code, ctlr_type,
1003 there,
1004 iom_cmd);
1005 if (rc)
1006 {
1007 return rc;
1008 }
1009
1010 here->in_use = false;
1011 here->iom_cmd = NULL;
1012 }
1013 else
1014 {
1015 if (here->in_use)
1016 {
1017 sim_printf ("%s: controller socket in use; unit number %u. dev_code %oo\r\n",
1018 service, ctlr_unit_idx, dev_code);
1019 return SCPE_ARG;
1020 }
1021
1022
1023 t_stat rc = cable_periph_to_ctlr (uncable,
1024 ctlr_unit_idx, dev_code, ctlr_type,
1025 there,
1026 iom_cmd);
1027 if (rc)
1028 {
1029 return rc;
1030 }
1031
1032 here->in_use = true;
1033 here->unit_idx = unit_idx;
1034 here->iom_cmd = iom_cmd;
1035 }
1036
1037 return SCPE_OK;
1038 }
1039
1040
1041
1042 static t_stat cable_mtp (int uncable, uint ctlr_unit_idx, char * * name_save)
1043 {
1044 if (ctlr_unit_idx >= mtp_dev.numunits)
1045 {
1046 sim_printf ("error: CABLE MTP: controller unit number out of range <%d>\r\n",
1047 ctlr_unit_idx);
1048 return SCPE_ARG;
1049 }
1050
1051 int dev_code = getval (name_save, "MTP device code");
1052
1053 if (dev_code < 0 || dev_code >= MAX_CHANNELS)
1054 {
1055 sim_printf ("error: CABLE MTP device code out of range <%d>\r\n",
1056 dev_code);
1057 return SCPE_ARG;
1058 }
1059
1060
1061 char * param = strtok_r (NULL, ", ", name_save);
1062 if (! param)
1063 {
1064 sim_printf ("error: CABLE IOM can't parse device name\r\n");
1065 return SCPE_ARG;
1066 }
1067 uint mt_unit_idx;
1068
1069
1070 if (name_match (param, "TAPE", & mt_unit_idx))
1071 {
1072 if (mt_unit_idx >= N_MT_UNITS_MAX)
1073 {
1074 sim_printf ("error: CABLE IOM: TAPE unit number out of range <%d>\r\n", mt_unit_idx);
1075 return SCPE_ARG;
1076 }
1077
1078 return cable_periph (uncable,
1079 ctlr_unit_idx,
1080 (uint) dev_code,
1081 CTLR_T_MTP,
1082 & cables->mtp_to_tape[ctlr_unit_idx][dev_code],
1083 mt_unit_idx,
1084 mt_iom_cmd,
1085 & cables->tape_to_mtp[mt_unit_idx],
1086 "CABLE MTPx TAPEx");
1087 }
1088
1089 sim_printf ("cable MTP: can't parse device name\r\n");
1090 return SCPE_ARG;
1091 }
1092
1093
1094
1095 static t_stat cable_ipc (int uncable, uint ctlr_unit_idx, char * * name_save)
1096 {
1097 if (ctlr_unit_idx >= ipc_dev.numunits)
1098 {
1099 sim_printf ("error: CABLE IPC: controller unit number out of range <%d>\r\n",
1100 ctlr_unit_idx);
1101 return SCPE_ARG;
1102 }
1103
1104 int dev_code = getval (name_save, "IPC device code");
1105
1106 if (dev_code < 0 || dev_code >= MAX_CHANNELS)
1107 {
1108 sim_printf ("error: CABLE IPC device code out of range <%d>\r\n",
1109 dev_code);
1110 return SCPE_ARG;
1111 }
1112
1113
1114 char * param = strtok_r (NULL, ", ", name_save);
1115 if (! param)
1116 {
1117 sim_printf ("error: CABLE IOM can't parse device name\r\n");
1118 return SCPE_ARG;
1119 }
1120 uint dsk_unit_idx;
1121
1122
1123 if (name_match (param, "DISK", & dsk_unit_idx))
1124 {
1125 if (dsk_unit_idx >= N_DSK_UNITS_MAX)
1126 {
1127 sim_printf ("error: CABLE IOM: DISK unit number out of range <%d>\r\n", dsk_unit_idx);
1128 return SCPE_ARG;
1129 }
1130
1131 return cable_periph (uncable,
1132 ctlr_unit_idx,
1133 (uint) dev_code,
1134 CTLR_T_IPC,
1135 & cables->ipc_to_dsk[ctlr_unit_idx][dev_code],
1136 dsk_unit_idx,
1137 dsk_iom_cmd,
1138 & cables->dsk_to_ctlr[dsk_unit_idx],
1139 "CABLE IPCx DISKx");
1140 }
1141
1142 sim_printf ("cable IPC: can't parse device name\r\n");
1143 return SCPE_ARG;
1144 }
1145
1146
1147
1148 static t_stat cable_msp (int uncable, uint ctlr_unit_idx, char * * name_save)
1149 {
1150 if (ctlr_unit_idx >= msp_dev.numunits)
1151 {
1152 sim_printf ("error: CABLE MSP: controller unit number out of range <%d>\r\n",
1153 ctlr_unit_idx);
1154 return SCPE_ARG;
1155 }
1156
1157 int dev_code = getval (name_save, "MSP device code");
1158
1159 if (dev_code < 0 || dev_code >= MAX_CHANNELS)
1160 {
1161 sim_printf ("error: CABLE MSP device code out of range <%d>\r\n",
1162 dev_code);
1163 return SCPE_ARG;
1164 }
1165
1166
1167 char * param = strtok_r (NULL, ", ", name_save);
1168 if (! param)
1169 {
1170 sim_printf ("error: CABLE IOM can't parse device name\r\n");
1171 return SCPE_ARG;
1172 }
1173 uint dsk_unit_idx;
1174
1175
1176 if (name_match (param, "DISK", & dsk_unit_idx))
1177 {
1178 if (dsk_unit_idx >= N_DSK_UNITS_MAX)
1179 {
1180 sim_printf ("error: CABLE IOM: DISK unit number out of range <%d>\r\n", dsk_unit_idx);
1181 return SCPE_ARG;
1182 }
1183
1184 return cable_periph (uncable,
1185 ctlr_unit_idx,
1186 (uint) dev_code,
1187 CTLR_T_MSP,
1188 & cables->msp_to_dsk[ctlr_unit_idx][dev_code],
1189 dsk_unit_idx,
1190 dsk_iom_cmd,
1191 & cables->dsk_to_ctlr[dsk_unit_idx],
1192 "CABLE MSPx DISKx");
1193 }
1194
1195 sim_printf ("cable MSP: can't parse device name\r\n");
1196 return SCPE_ARG;
1197 }
1198
1199
1200
1201 static t_stat cable_urp (int uncable, uint ctlr_unit_idx, char * * name_save)
1202 {
1203 if (ctlr_unit_idx >= urp_dev.numunits)
1204 {
1205 sim_printf ("error: CABLE URP: controller unit number out of range <%d>\r\n",
1206 ctlr_unit_idx);
1207 return SCPE_ARG;
1208 }
1209
1210 int dev_code = getval (name_save, "URP device code");
1211
1212 if (dev_code < 0 || dev_code >= MAX_CHANNELS)
1213 {
1214 sim_printf ("error: CABLE URP device code out of range <%d>\r\n",
1215 dev_code);
1216 return SCPE_ARG;
1217 }
1218
1219
1220 char * param = strtok_r (NULL, ", ", name_save);
1221 if (! param)
1222 {
1223 sim_printf ("error: CABLE IOM can't parse device name\r\n");
1224 return SCPE_ARG;
1225 }
1226 uint unit_idx;
1227
1228
1229 if (name_match (param, "RDR", & unit_idx))
1230 {
1231 if (unit_idx >= N_RDR_UNITS_MAX)
1232 {
1233 sim_printf ("error: CABLE IOM: DISK unit number out of range <%d>\r\n", unit_idx);
1234 return SCPE_ARG;
1235 }
1236
1237 return cable_periph (uncable,
1238 ctlr_unit_idx,
1239 (uint) dev_code,
1240 CTLR_T_URP,
1241 & cables->urp_to_urd[ctlr_unit_idx][dev_code],
1242 unit_idx,
1243 rdr_iom_cmd,
1244 & cables->rdr_to_urp[unit_idx],
1245 "CABLE URPx RDRx");
1246 }
1247
1248
1249 if (name_match (param, "PUN", & unit_idx))
1250 {
1251 if (unit_idx >= N_PUN_UNITS_MAX)
1252 {
1253 sim_printf ("error: CABLE IOM: DISK unit number out of range <%d>\r\n", unit_idx);
1254 return SCPE_ARG;
1255 }
1256
1257 return cable_periph (uncable,
1258 ctlr_unit_idx,
1259 (uint) dev_code,
1260 CTLR_T_URP,
1261 & cables->urp_to_urd[ctlr_unit_idx][dev_code],
1262 unit_idx,
1263 pun_iom_cmd,
1264 & cables->pun_to_urp[unit_idx],
1265 "CABLE URPx PUNx");
1266 }
1267
1268
1269 if (name_match (param, "PRT", & unit_idx))
1270 {
1271 if (unit_idx >= N_PRT_UNITS_MAX)
1272 {
1273 sim_printf ("error: CABLE IOM: DISK unit number out of range <%d>\r\n", unit_idx);
1274 return SCPE_ARG;
1275 }
1276
1277 return cable_periph (uncable,
1278 ctlr_unit_idx,
1279 (uint) dev_code,
1280 CTLR_T_URP,
1281 & cables->urp_to_urd[ctlr_unit_idx][dev_code],
1282 unit_idx,
1283 prt_iom_cmd,
1284 & cables->prt_to_urp[unit_idx],
1285 "CABLE URPx PRTx");
1286 }
1287
1288 sim_printf ("cable URP: can't parse device name\r\n");
1289 return SCPE_ARG;
1290 }
1291
1292 t_stat sys_cable (int32 arg, const char * buf)
1293 {
1294 char * copy = strdup (buf);
1295 if (!copy)
1296 {
1297 (void)fprintf (stderr, "\rFATAL: Out of memory! Aborting at %s[%s:%d]\r\n",
1298 __func__, __FILE__, __LINE__);
1299 #if defined(USE_BACKTRACE)
1300 # if defined(SIGUSR2)
1301 (void)raise(SIGUSR2);
1302
1303 # endif
1304 #endif
1305 abort();
1306 }
1307 t_stat rc = SCPE_ARG;
1308
1309
1310
1311
1312 char * name_save = NULL;
1313 char * name;
1314 name = strtok_r (copy, ", \t", & name_save);
1315 if (! name)
1316 {
1317
1318 sim_printf ("error: CABLE: sys_cable could not parse name\r\n");
1319 goto exit;
1320 }
1321
1322 uint unit_num;
1323 if (strcasecmp (name, "RIPOUT") == 0)
1324 rc = sys_cable_ripout (0, NULL);
1325 else if (strcasecmp (name, "SHOW") == 0)
1326 rc = sys_cable_show (0, NULL);
1327 else if (strcasecmp (name, "DUMP") == 0)
1328 rc = sys_cable_show (1, NULL);
1329 else if (strcasecmp (name, "GRAPH") == 0)
1330 rc = sys_cable_graph ();
1331 else if (name_match (name, "SCU", & unit_num))
1332 rc = cable_scu (arg, unit_num, & name_save);
1333 else if (name_match (name, "IOM", & unit_num))
1334 rc = cable_iom (arg, unit_num, & name_save);
1335 else if (name_match (name, "MTP", & unit_num))
1336 rc = cable_mtp (arg, unit_num, & name_save);
1337 else if (name_match (name, "IPC", & unit_num))
1338 rc = cable_ipc (arg, unit_num, & name_save);
1339 else if (name_match (name, "MSP", & unit_num))
1340 rc = cable_msp (arg, unit_num, & name_save);
1341 else if (name_match (name, "URP", & unit_num))
1342 rc = cable_urp (arg, unit_num, & name_save);
1343 else
1344 {
1345 sim_printf ("error: CABLE: Invalid name <%s>\r\n", name);
1346 goto exit;
1347 }
1348 if (name_save && strlen (name_save))
1349 {
1350 sim_printf ("CABLE ignored '%s'\r\n", name_save);
1351 }
1352 exit:
1353 FREE (copy);
1354 return rc;
1355 }
1356
1357 static void cable_init (void)
1358 {
1359
1360
1361
1362 (void)memset (cables, 0, sizeof (struct cables_s));
1363 }
1364
1365 #define all(i,n) \
1366 for (uint i = 0; i < n; i ++)
1367
1368 static t_stat
1369 sys_cable_graph (void)
1370 {
1371
1372 bool cpus_used[N_CPU_UNITS_MAX];
1373 (void)memset (cpus_used, 0, sizeof (cpus_used));
1374
1375 all (u, N_CPU_UNITS_MAX) all (prt, N_CPU_PORTS)
1376 {
1377 struct cpu_to_scu_s *p = &cables->cpu_to_scu[u][prt];
1378 if (p->in_use)
1379 cpus_used[u] = true;
1380 }
1381
1382
1383 bool scus_used[N_SCU_UNITS_MAX];
1384 (void)memset (scus_used, 0, sizeof (scus_used));
1385
1386 all (u, N_SCU_UNITS_MAX) all (prt, N_SCU_PORTS)
1387 {
1388 struct scu_to_iom_s *p = &cables->scu_to_iom[u][prt];
1389 if (p->in_use)
1390 scus_used[u] = true;
1391 }
1392 all (u, N_CPU_UNITS_MAX) all (prt, N_CPU_PORTS)
1393 {
1394 struct cpu_to_scu_s *p = &cables->cpu_to_scu[u][prt];
1395 if (p->in_use)
1396 scus_used[p->scu_unit_idx] = true;
1397 }
1398
1399
1400 bool ioms_used[N_IOM_UNITS_MAX];
1401 (void)memset (ioms_used, 0, sizeof (ioms_used));
1402
1403 all (u, N_SCU_UNITS_MAX) all (prt, N_SCU_PORTS)
1404 {
1405 struct scu_to_iom_s *p = &cables->scu_to_iom[u][prt];
1406 if (p->in_use)
1407 ioms_used[p->iom_unit_idx] = true;
1408 }
1409
1410
1411 sim_printf ("graph {\r\n");
1412 sim_printf (" rankdir=TD;\r\n");
1413
1414
1415 sim_printf (" { rank=same; ");
1416 for (int i = 0; i < N_CPU_UNITS_MAX; i++)
1417 if (cpus_used[i])
1418 sim_printf (" CPU%c [shape=diamond, \
1419 color=lightgreen, \
1420 style=filled];",
1421 i + 'A');
1422 sim_printf ("}\r\n");
1423
1424
1425 sim_printf (" { rank=same; ");
1426 for (int i = 0; i < N_SCU_UNITS_MAX; i++)
1427 if (scus_used[i])
1428 sim_printf (" SCU%c [shape=doubleoctagon, \
1429 color=deepskyblue4, \
1430 style=filled];",
1431 i + 'A');
1432 sim_printf ("}\r\n");
1433
1434
1435 sim_printf (" { rank=same; ");
1436 for (int i = 0; i < N_IOM_UNITS_MAX; i++)
1437 if (ioms_used[i])
1438 sim_printf (" IOM%c [shape=doublecircle, \
1439 color=cadetblue4, \
1440 style=filled];",
1441 i + 'A');
1442 sim_printf ("}\r\n");
1443
1444 #define R_CTLR_IOM(big, small, shape, color) \
1445 sim_printf (" { rank=same; "); \
1446 all (u, N_ ## big ## _UNITS_MAX) all (prt, MAX_CTLR_PORTS) \
1447 { \
1448 struct ctlr_to_iom_s *p = &cables->small ## _to_iom[u][prt]; \
1449 if (p->in_use) \
1450 sim_printf (" %s%d [shape=%s, color=%s, style=filled];", \
1451 #big, u, #shape, #color); \
1452 } \
1453 sim_printf ("}\r\n");
1454
1455 R_CTLR_IOM (MTP, mtp, oval, firebrick1)
1456 R_CTLR_IOM (MSP, msp, oval, firebrick2)
1457 R_CTLR_IOM (IPC, ipc, oval, firebrick3)
1458 R_CTLR_IOM (FNP, fnp, egg, snow2)
1459 R_CTLR_IOM (URP, urp, polygon, gold4)
1460 R_CTLR_IOM (DIA, dia, oval, orange)
1461 #if defined(WITH_ABSI_DEV)
1462 # if !defined(__MINGW64__)
1463 R_CTLR_IOM (ABSI, absi, oval, teal)
1464 # endif
1465 #endif
1466 #if defined(WITH_MGP_DEV)
1467 R_CTLR_IOM (MGP, mgp, oval, teal)
1468 #endif
1469 #if defined(WITH_NET_DEV)
1470 R_CTLR_IOM (NET, net, oval, teal)
1471 #endif
1472 R_CTLR_IOM (OPC, opc, oval, hotpink)
1473
1474 #define R_DEV_CTLR(from_big, from_small, to_label, \
1475 to_big, to_small, shape, color) \
1476 sim_printf (" { rank=same; "); \
1477 all (u, N_ ## to_big ## _UNITS_MAX) \
1478 { \
1479 struct dev_to_ctlr_s *p = \
1480 &cables->to_small ## _to_ ## from_small[u]; \
1481 if (p->in_use) \
1482 sim_printf (" %s%d [shape=%s, style=filled, color=%s];", \
1483 #to_label, u, #shape, #color); \
1484 } \
1485 sim_printf ("}\r\n");
1486
1487 R_DEV_CTLR (MTP, mtp, TAPE, MT, tape, oval, aquamarine3);
1488 R_DEV_CTLR (CTLR, ctlr, DISK, DSK, dsk, cylinder, bisque3);
1489 R_DEV_CTLR (URP, urp, RDR, RDR, rdr, septagon, mediumpurple1);
1490 R_DEV_CTLR (URP, urp, PUN, PUN, pun, pentagon, maroon3);
1491 R_DEV_CTLR (URP, urp, PRT, PRT, prt, octagon, yellowgreen);
1492
1493
1494 all (u, N_CPU_UNITS_MAX) all (prt, N_CPU_PORTS)
1495 {
1496 struct cpu_to_scu_s *p = &cables->cpu_to_scu[u][prt];
1497 if (p->in_use)
1498 sim_printf (" CPU%c -- SCU%c;\r\n", u + 'A',
1499 p->scu_unit_idx + 'A');
1500 }
1501
1502
1503 all (u, N_SCU_UNITS_MAX) all (prt, N_SCU_PORTS)
1504 {
1505 struct scu_to_iom_s *p = &cables->scu_to_iom[u][prt];
1506 if (p->in_use)
1507 sim_printf (" SCU%c -- IOM%c;\r\n", u + 'A',
1508 p->iom_unit_idx + 'A');
1509 }
1510
1511
1512 all (u, N_IOM_UNITS_MAX) all (c, MAX_CHANNELS)
1513 {
1514 struct iom_to_ctlr_s *p = &cables->iom_to_ctlr[u][c];
1515 if (p->in_use)
1516 sim_printf (" IOM%c -- %s%d;\r\n", u + 'A',
1517 ctlr_type_strs[p->ctlr_type],
1518 p->ctlr_unit_idx);
1519 }
1520
1521
1522 #define G_DEV_CTLR(from_big, from_small, to_label, to_big, to_small) \
1523 all (u, N_ ## to_big ## _UNITS_MAX) \
1524 { \
1525 struct dev_to_ctlr_s *p = \
1526 &cables->to_small ## _to_ ## from_small[u]; \
1527 if (p->in_use) \
1528 sim_printf (" %s%d -- %s%d;\r\n", \
1529 ctlr_type_strs[p->ctlr_type], \
1530 p->ctlr_unit_idx, #to_label, u); \
1531 }
1532
1533 G_DEV_CTLR (MTP, mtp, TAPE, MT, tape);
1534 G_DEV_CTLR (CTLR, ctlr, DISK, DSK, dsk);
1535 G_DEV_CTLR (URP, urp, RDR, RDR, rdr);
1536 G_DEV_CTLR (URP, urp, PUN, PUN, pun);
1537 G_DEV_CTLR (URP, urp, PRT, PRT, prt);
1538
1539 sim_printf ("}\r\n");
1540 return SCPE_OK;
1541 }
1542
1543 t_stat sys_cable_show (int32 dump, UNUSED const char * buf)
1544 {
1545 sim_printf ("SCU <--> IOM\r\n");
1546 sim_printf (" SCU port --> IOM port\r\n");
1547 all (u, N_SCU_UNITS_MAX)
1548 all (prt, N_SCU_PORTS)
1549 {
1550 struct scu_to_iom_s * p = & cables->scu_to_iom[u][prt];
1551 if (p->in_use)
1552 sim_printf (" %4u %4u %4u %4u\r\n", u, prt, p->iom_unit_idx, p->iom_port_num);
1553 }
1554
1555 if (dump)
1556 {
1557 sim_printf (" IOM port --> SCU port\r\n");
1558 all (u, N_IOM_UNITS_MAX)
1559 all (prt, N_IOM_PORTS)
1560 {
1561 struct iom_to_scu_s * p = & cables->iom_to_scu[u][prt];
1562 if (p->in_use)
1563 sim_printf (" %4u %4u %4u %4u\r\n", u, prt, p->scu_unit_idx, p->scu_port_num);
1564 }
1565 }
1566 sim_printf ("\r\n");
1567
1568 sim_printf ("SCU <--> CPU\r\n");
1569 sim_printf (" SCU port --> CPU port\r\n");
1570 all (u, N_SCU_UNITS_MAX)
1571 all (prt, N_SCU_PORTS)
1572 all (sp, N_SCU_SUBPORTS)
1573 {
1574 struct scu_to_cpu_s * p = & cables->scu_to_cpu[u][prt][sp];
1575 if (p->in_use)
1576 sim_printf (" %4u %4u %4u %4u\r\n", u, prt, p->cpu_unit_idx, p->cpu_port_num);
1577 }
1578
1579 if (dump)
1580 {
1581 sim_printf (" CPU port --> SCU port subport\r\n");
1582 all (u, N_CPU_UNITS_MAX)
1583 all (prt, N_CPU_PORTS)
1584 {
1585 struct cpu_to_scu_s * p = & cables->cpu_to_scu[u][prt];
1586 if (p->in_use)
1587 sim_printf (" %4u %4u %4u %4u %4u\r\n",
1588 u, prt, p->scu_unit_idx, p->scu_port_num, p->scu_subport_num);
1589 }
1590 }
1591 sim_printf ("\r\n");
1592
1593 sim_printf ("IOM <--> controller\r\n");
1594 sim_printf (" ctlr ctlr chan\r\n");
1595 sim_printf (" IOM chan --> idx port type type device board command\r\n");
1596 all (u, N_IOM_UNITS_MAX)
1597 all (c, MAX_CHANNELS)
1598 {
1599 struct iom_to_ctlr_s * p = & cables->iom_to_ctlr[u][c];
1600 if (p->in_use)
1601 sim_printf (" %4u %4u %4u %4u %-6s %-6s %10p %10p %10p\r\n",
1602 u, c, p->ctlr_unit_idx, p->port_num, ctlr_type_strs[p->ctlr_type],
1603 chan_type_strs[p->chan_type], (void *) p->dev,
1604 (void *) p->board, (void *) p->iom_cmd);
1605 }
1606
1607 if (dump)
1608 {
1609 #define CTLR_IOM(big,small) \
1610 sim_printf (" %-4s port --> IOM channel\r\n", #big); \
1611 all (u, N_ ## big ## _UNITS_MAX) \
1612 all (prt, MAX_CTLR_PORTS) \
1613 { \
1614 struct ctlr_to_iom_s * p = & cables->small ## _to_iom[u][prt]; \
1615 if (p->in_use) \
1616 sim_printf (" %4u %4u %4u %4u\r\n", u, prt, p->iom_unit_idx, p->chan_num); \
1617 }
1618 CTLR_IOM (MTP, mtp)
1619 CTLR_IOM (MSP, msp)
1620 CTLR_IOM (IPC, ipc)
1621 CTLR_IOM (URP, urp)
1622 CTLR_IOM (FNP, fnp)
1623 CTLR_IOM (DIA, dia)
1624 #if defined(WITH_ABSI_DEV)
1625 # if !defined(__MINGW64__) && !defined(__MINGW32__) && !defined(CROSS_MINGW32) && !defined(CROSS_MINGW64)
1626 CTLR_IOM (ABSI, absi)
1627 # endif
1628 #endif
1629 #if defined(WITH_MGP_DEV)
1630 CTLR_IOM (MGP, mgp)
1631 #endif
1632 #if defined(WITH_NET_DEV)
1633 CTLR_IOM (NET, net)
1634 #endif
1635 #if defined(WITH_SOCKET_DEV)
1636 # if !defined(__MINGW32__) && !defined(__MINGW64__) && !defined(CROSS_MINGW32) && !defined(CROSS_MINGW64)
1637 CTLR_IOM (SKC, sk)
1638 # endif
1639 #endif
1640 CTLR_IOM (OPC, opc)
1641 }
1642 sim_printf ("\r\n");
1643
1644 sim_printf ("controller <--> device\r\n");
1645
1646 #define CTLR_DEV(from_big,from_small, to_label, to_big, to_small) \
1647 sim_printf (" %-4s dev_code --> %-4s command\r\n", #from_big, #to_label); \
1648 all (u, N_ ## from_big ## _UNITS_MAX) \
1649 all (prt, N_DEV_CODES) \
1650 { \
1651 struct ctlr_to_dev_s * p = & cables->from_small ## _to_ ## to_small[u][prt]; \
1652 if (p->in_use) \
1653 sim_printf (" %4u %4u %4u %10p\r\n", u, prt, p->unit_idx, (void *) p->iom_cmd); \
1654 }
1655 #define DEV_CTLR(from_big,from_small, to_label, to_big, to_small) \
1656 sim_printf (" %-4s --> %-4s dev_code type\r\n", #to_label, #from_big); \
1657 all (u, N_ ## to_big ## _UNITS_MAX) \
1658 { \
1659 struct dev_to_ctlr_s * p = & cables->to_small ## _to_ ## from_small[u]; \
1660 if (p->in_use) \
1661 sim_printf (" %4u %4u %4u %5s\r\n", u, p->ctlr_unit_idx, \
1662 p->dev_code, ctlr_type_strs[p->ctlr_type]); \
1663 }
1664 CTLR_DEV (MTP, mtp, TAPE, MT, tape);
1665 if (dump)
1666 {
1667 DEV_CTLR (MTP, mtp, TAPE, MT, tape);
1668 }
1669 CTLR_DEV (IPC, ipc, DISK, DSK, dsk);
1670 CTLR_DEV (MSP, msp, DISK, DSK, dsk);
1671 if (dump)
1672 {
1673 DEV_CTLR (CTLR, ctlr, DISK, DSK, dsk);
1674 }
1675 CTLR_DEV (URP, urp, URP, URP, urd);
1676 if (dump)
1677 {
1678 DEV_CTLR (URP, urp, RDR, RDR, rdr);
1679 }
1680 if (dump)
1681 {
1682 DEV_CTLR (URP, urp, PUN, PUN, pun);
1683 }
1684 if (dump)
1685 {
1686 DEV_CTLR (URP, urp, PRT, PRT, prt);
1687 }
1688
1689 return SCPE_OK;
1690 }
1691
1692 t_stat sys_cable_ripout (UNUSED int32 arg, UNUSED const char * buf)
1693 {
1694 cable_init ();
1695 scu_init ();
1696 return SCPE_OK;
1697 }
1698
1699 void sysCableInit (void)
1700 {
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717 cables = & system_state->cables;
1718
1719
1720 cable_init ();
1721 }