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