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