This source file includes following definitions.
- prt_init
- prt_reset
- gc
- parseID
- openPrtFile
- eoj
- print_buf
- loadImageBuffer
- readStatusRegister
- loadVFCImage
- print_cmd
- prt_cmd_202
- prt_cmd_300
- prt_cmd_300a
- prt_cmd_400
- prt_iom_cmd
- prt_show_nunits
- prt_set_nunits
- prt_show_device_name
- prt_set_device_model
- prt_show_device_model
- prt_set_device_name
- prt_show_path
- prt_set_path
- burst_printer
- signal_prt_ready
- prt_set_ready
- prt_set_config
- prt_show_config
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 #include <stdio.h>
35 #include <ctype.h>
36 #include <unistd.h>
37
38 #include "dps8.h"
39 #include "dps8_iom.h"
40 #include "dps8_prt.h"
41 #include "dps8_sys.h"
42 #include "dps8_faults.h"
43 #include "dps8_scu.h"
44 #include "dps8_cable.h"
45 #include "dps8_cpu.h"
46 #include "dps8_utils.h"
47 #include "utfile.h"
48
49 #define DBG_CTR 1
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 #define N_PRT_UNITS 1
84
85 static t_stat prt_reset (DEVICE * dptr);
86 static t_stat prt_show_nunits (FILE *st, UNIT *uptr, int val, const void *desc);
87 static t_stat prt_set_nunits (UNIT * uptr, int32 value, const char * cptr, void * desc);
88 static t_stat prt_show_device_name (FILE *st, UNIT *uptr, int val, const void *desc);
89 static t_stat prt_set_device_name (UNIT * uptr, int32 value, const char * cptr, void * desc);
90 static t_stat prt_set_config (UNUSED UNIT * uptr, UNUSED int32 value,
91 const char * cptr, UNUSED void * desc);
92 static t_stat prt_show_config (UNUSED FILE * st, UNUSED UNIT * uptr,
93 UNUSED int val, UNUSED const void * desc);
94 static t_stat prt_show_path (UNUSED FILE * st, UNIT * uptr,
95 UNUSED int val, UNUSED const void * desc);
96 static t_stat prt_set_path (UNUSED UNIT * uptr, UNUSED int32 value,
97 const UNUSED char * cptr, UNUSED void * desc);
98 static t_stat prt_set_ready (UNIT * uptr, UNUSED int32 value,
99 UNUSED const char * cptr,
100 UNUSED void * desc);
101
102 static t_stat prt_show_device_model (FILE *st, UNIT *uptr, int val, const void *desc);
103 static t_stat prt_set_device_model (UNIT * uptr, int32 value, const char * cptr, void * desc);
104
105 #define UNIT_FLAGS ( UNIT_FIX | UNIT_ATTABLE | UNIT_ROABLE | UNIT_DISABLE | \
106 UNIT_IDLE )
107 UNIT prt_unit[N_PRT_UNITS_MAX] =
108 {
109 {UDATA (NULL, UNIT_FLAGS, 0), 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL},
110 {UDATA (NULL, UNIT_FLAGS, 0), 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL},
111 {UDATA (NULL, UNIT_FLAGS, 0), 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL},
112 {UDATA (NULL, UNIT_FLAGS, 0), 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL},
113 {UDATA (NULL, UNIT_FLAGS, 0), 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL},
114 {UDATA (NULL, UNIT_FLAGS, 0), 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL},
115 {UDATA (NULL, UNIT_FLAGS, 0), 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL},
116 {UDATA (NULL, UNIT_FLAGS, 0), 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL},
117 {UDATA (NULL, UNIT_FLAGS, 0), 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL},
118 {UDATA (NULL, UNIT_FLAGS, 0), 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL},
119 {UDATA (NULL, UNIT_FLAGS, 0), 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL},
120 {UDATA (NULL, UNIT_FLAGS, 0), 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL},
121 {UDATA (NULL, UNIT_FLAGS, 0), 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL},
122 {UDATA (NULL, UNIT_FLAGS, 0), 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL},
123 {UDATA (NULL, UNIT_FLAGS, 0), 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL},
124 {UDATA (NULL, UNIT_FLAGS, 0), 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL},
125 {UDATA (NULL, UNIT_FLAGS, 0), 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL},
126 {UDATA (NULL, UNIT_FLAGS, 0), 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL},
127 {UDATA (NULL, UNIT_FLAGS, 0), 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL},
128 {UDATA (NULL, UNIT_FLAGS, 0), 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL},
129 {UDATA (NULL, UNIT_FLAGS, 0), 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL},
130 {UDATA (NULL, UNIT_FLAGS, 0), 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL},
131 {UDATA (NULL, UNIT_FLAGS, 0), 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL},
132 {UDATA (NULL, UNIT_FLAGS, 0), 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL},
133 {UDATA (NULL, UNIT_FLAGS, 0), 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL},
134 {UDATA (NULL, UNIT_FLAGS, 0), 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL},
135 {UDATA (NULL, UNIT_FLAGS, 0), 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL},
136 {UDATA (NULL, UNIT_FLAGS, 0), 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL},
137 {UDATA (NULL, UNIT_FLAGS, 0), 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL},
138 {UDATA (NULL, UNIT_FLAGS, 0), 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL},
139 {UDATA (NULL, UNIT_FLAGS, 0), 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL},
140 {UDATA (NULL, UNIT_FLAGS, 0), 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL},
141 {UDATA (NULL, UNIT_FLAGS, 0), 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL},
142 {UDATA (NULL, UNIT_FLAGS, 0), 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL}
143 };
144
145 #define PRT_UNIT_NUM(uptr) ((uptr) - prt_unit)
146
147 static DEBTAB prt_dt[] =
148 {
149 { "NOTIFY", DBG_NOTIFY, NULL },
150 { "INFO", DBG_INFO, NULL },
151 { "ERR", DBG_ERR, NULL },
152 { "WARN", DBG_WARN, NULL },
153 { "DEBUG", DBG_DEBUG, NULL },
154 { "ALL", DBG_ALL, NULL },
155 { NULL, 0, NULL }
156 };
157
158 #define UNIT_WATCH UNIT_V_UF
159
160 static MTAB prt_mod[] =
161 {
162 #ifndef SPEED
163 { UNIT_WATCH, 1, "WATCH", "WATCH", 0, 0, NULL, NULL },
164 { UNIT_WATCH, 0, "NOWATCH", "NOWATCH", 0, 0, NULL, NULL },
165 #endif
166 {
167 MTAB_XTD | MTAB_VDV | MTAB_NMO | MTAB_VALR,
168 0,
169 "NUNITS",
170 "NUNITS",
171 prt_set_nunits,
172 prt_show_nunits,
173 "Number of PRT units in the system",
174 NULL
175 },
176 {
177 MTAB_XTD | MTAB_VDV | MTAB_NMO | \
178 MTAB_VALR | MTAB_NC,
179 0,
180 "PATH",
181 "PATH",
182 prt_set_path,
183 prt_show_path,
184 "Path to write PRT files",
185 NULL
186 },
187 {
188 MTAB_XTD | MTAB_VUN | MTAB_VALR | MTAB_NC,
189 0,
190 "NAME",
191 "NAME",
192 prt_set_device_name,
193 prt_show_device_name,
194 "Select the printer name",
195 NULL
196 },
197
198 {
199 MTAB_XTD | MTAB_VUN | MTAB_VALR | MTAB_NC,
200 0,
201 "MODEL",
202 "MODEL",
203 prt_set_device_model,
204 prt_show_device_model,
205 "Select the printer model",
206 NULL
207 },
208 {
209 MTAB_XTD | MTAB_VUN,
210 0,
211 (char *) "CONFIG",
212 (char *) "CONFIG",
213 prt_set_config,
214 prt_show_config,
215 NULL,
216 NULL,
217 },
218 {
219 MTAB_XTD | MTAB_VUN | MTAB_NMO | MTAB_VALR,
220 0,
221 "READY",
222 "READY",
223 prt_set_ready,
224 NULL,
225 NULL,
226 NULL
227 },
228 { 0, 0, NULL, NULL, 0, 0, NULL, NULL }
229 };
230
231 DEVICE prt_dev = {
232 "PRT",
233 prt_unit,
234 NULL,
235 prt_mod,
236 N_PRT_UNITS,
237 10,
238 24,
239 1,
240 8,
241 36,
242 NULL,
243 NULL,
244 prt_reset,
245 NULL,
246 NULL,
247 NULL,
248 NULL,
249 DEV_DEBUG,
250 0,
251 prt_dt,
252 NULL,
253 NULL,
254 NULL,
255 NULL,
256 NULL,
257 NULL,
258 NULL
259 };
260
261 typedef struct
262 {
263 enum prt_mode
264 {
265 prtNoMode, prtPrt, prtLdImgBuf, prtRdStatReg, prtLdVFCImg
266 } ioMode;
267 int prtUnitNum;
268 bool isBCD;
269 bool isEdited;
270 int slew;
271 char device_name[MAX_DEV_NAME_LEN];
272 int prtfile;
273
274 bool cachedFF;
275 bool split;
276 int model;
277 } prt_state_t;
278
279 static prt_state_t prt_state[N_PRT_UNITS_MAX];
280
281 static char prt_path[1025];
282
283 #define N_MODELS 13
284
285 static const char * model_names[N_MODELS] =
286 {
287 "202", "300", "301", "302", "303", "304",
288 "401", "402", "901", "1000", "1200", "1201",
289 "1600"
290 };
291
292 #define MODEL_1600 12
293
294 static const int model_type[N_MODELS] =
295 { 1, 2, 2, 2, 3, 3,
296 4, 4, 4, 4, 4, 4,
297 4
298 };
299
300 #ifdef NO_C_ELLIPSIS
301 static const uint8 newlines[128] = {
302 '\n', '\n', '\n', '\n', '\n', '\n', '\n', '\n',
303 '\n', '\n', '\n', '\n', '\n', '\n', '\n', '\n',
304 '\n', '\n', '\n', '\n', '\n', '\n', '\n', '\n',
305 '\n', '\n', '\n', '\n', '\n', '\n', '\n', '\n',
306 '\n', '\n', '\n', '\n', '\n', '\n', '\n', '\n',
307 '\n', '\n', '\n', '\n', '\n', '\n', '\n', '\n',
308 '\n', '\n', '\n', '\n', '\n', '\n', '\n', '\n',
309 '\n', '\n', '\n', '\n', '\n', '\n', '\n', '\n',
310 '\n', '\n', '\n', '\n', '\n', '\n', '\n', '\n',
311 '\n', '\n', '\n', '\n', '\n', '\n', '\n', '\n',
312 '\n', '\n', '\n', '\n', '\n', '\n', '\n', '\n',
313 '\n', '\n', '\n', '\n', '\n', '\n', '\n', '\n',
314 '\n', '\n', '\n', '\n', '\n', '\n', '\n', '\n',
315 '\n', '\n', '\n', '\n', '\n', '\n', '\n', '\n',
316 '\n', '\n', '\n', '\n', '\n', '\n', '\n', '\n',
317 '\n', '\n', '\n', '\n', '\n', '\n', '\n', '\n'
318 };
319
320 static const uint8 spaces[128] = {
321 ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
322 ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
323 ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
324 ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
325 ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
326 ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
327 ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
328 ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
329 ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
330 ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
331 ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
332 ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
333 ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
334 ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
335 ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
336 ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '
337 };
338 #else
339 static const uint8 newlines[128] = { [0 ... 127] = '\n' };
340 static const uint8 spaces[128] = { [0 ... 127] = ' ' };
341 #endif
342 static const uint8 formfeed[1] = { '\f' };
343 static const uint8 crlf[4] = { '\r', '\n', '\r', '\n' };
344 static const uint8 cr[2] = { '\r', '\n' };
345
346
347
348
349
350
351
352
353 void prt_init (void)
354 {
355 memset (prt_path, 0, sizeof (prt_path));
356 memset (prt_state, 0, sizeof (prt_state));
357 for (int i = 0; i < N_PRT_UNITS_MAX; i ++)
358 {
359 prt_state[i].prtfile = -1;
360 prt_state[i].model = MODEL_1600;
361 }
362 }
363
364 static t_stat prt_reset (UNUSED DEVICE * dptr)
365 {
366
367
368
369
370
371
372
373 return SCPE_OK;
374 }
375
376
377
378 static word9 gc (word36 * b, uint os)
379 {
380 uint wordno = os / 4;
381 uint charno = os % 4;
382 return (word9) getbits36_9 (b[wordno], charno * 9);
383 }
384
385
386 #define LONGEST 128
387
388
389
390
391
392
393
394 static int parseID (word36 * b, uint tally, char * qno, char * name)
395 {
396 if (tally < 3)
397 return 0;
398 if (gc (b, 0) != 040)
399 return 0;
400 if (gc (b, 1) != 040)
401 return 0;
402 uint i;
403 for (i = 0; i < 5; i ++)
404 {
405 word9 ch = gc (b, 2 + i);
406 if (ch < '0' || ch > '9')
407 return 0;
408 qno[i] = (char) ch;
409 }
410 qno[5] = 0;
411 if (gc (b, 7) != 037)
412 return 0;
413
414
415 for (i = 0; i < LONGEST; i ++)
416 {
417 word9 ch = gc (b, 9 + i);
418 if (ch == 037)
419 break;
420 if (! isprint (ch))
421 return 0;
422 name[i] = (char) ch;
423 }
424 name[i] = 0;
425 return -1;
426 }
427
428
429
430
431
432
433 static int openPrtFile (int prt_unit_num, word36 * buffer, uint tally)
434 {
435 if (prt_state[prt_unit_num].prtfile != -1)
436 return 0;
437
438
439
440
441 if (tally == 1 && buffer[0] == 0014013000000llu)
442 {
443 prt_state[prt_unit_num].cachedFF = true;
444 return -3;
445 }
446
447 char qno[6], name[LONGEST + 1];
448 int rc = parseID (buffer, tally, qno, name);
449 char template[1024 + 129 + LONGEST];
450 char unit_designator = 'a' + (char) prt_unit_num;
451 char split_prefix[6];
452 split_prefix[0] = 0;
453 if (prt_state [prt_unit_num] . split) {
454 sprintf(split_prefix, "prt%c/", unit_designator);
455 }
456 if (rc == 0)
457 sprintf (template, "%s%sprt%c.spool.XXXXXX.prt", prt_path, split_prefix, unit_designator);
458 else
459 sprintf (template, "%s%sprt%c.spool.%s.%s.XXXXXX.prt", prt_path, split_prefix, unit_designator, qno, name);
460
461 prt_state[prt_unit_num].prtfile = utfile_mkstemps (template, 4);
462 if (prt_state[prt_unit_num].prtfile == -1)
463 {
464 sim_warn ("Unable to open printer file '%s', errno %d\n", template, errno);
465 return -1;
466 }
467 if (prt_state[prt_unit_num].cachedFF)
468 {
469 ssize_t n_write = write (prt_state[prt_unit_num].prtfile, formfeed, 1);
470 if (n_write != 1)
471 {
472 return -2;
473 }
474 prt_state[prt_unit_num].cachedFF = false;
475 }
476 return 0;
477 }
478
479
480 static int eoj (word36 * buffer, uint tally)
481 {
482 if (tally < 3)
483 return 0;
484 if (getbits36_9 (buffer[0], 0) != 037)
485 return 0;
486 if (getbits36_9 (buffer[0], 9) != 014)
487 return 0;
488 word9 ch = getbits36_9 (buffer[0], 18);
489 if (ch < '0' || ch > '9')
490 return 0;
491 ch = getbits36_9 (buffer[0], 27);
492 if (ch < '0' || ch > '9')
493 return 0;
494 ch = getbits36_9 (buffer[1], 0);
495 if (ch < '0' || ch > '9')
496 return 0;
497 ch = getbits36_9 (buffer[1], 9);
498 if (ch < '0' || ch > '9')
499 return 0;
500 ch = getbits36_9 (buffer[1], 18);
501 if (ch < '0' || ch > '9')
502 return 0;
503 if (getbits36_9 (buffer[1], 27) != 037)
504 return 0;
505 if (getbits36_9 (buffer[2], 0) != 005)
506 return 0;
507 return -1;
508 }
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619 static int print_buf (int prt_unit_num, bool isBCD, bool is_edited, int slew, word36 * buffer, uint tally)
620 {
621
622
623
624
625
626
627
628
629
630
631
632
633 static char * bcd_lc =
634 "01234567"
635 "89{#?;>?"
636 " abcdefg"
637 "hi|.}(<\\"
638 "^jklmnop"
639 "qr_$*);'"
640 "+/stuvwx"
641 "yz~,!=\"!";
642
643
644
645
646
647
648
649
650
651
652
653
654 static char * bcd_uc =
655 "01234567"
656 "89[#@;>?"
657 " ABCDEFG"
658 "HI&.](<\\"
659 "^JKLMNOP"
660 "QR-$*);'"
661 "+/STUVWX"
662 "YZ_,%=\"!";
663
664
665 static char * bcd =
666 "01234567"
667 "89[#@;> "
668 " ABCDEFG"
669 "HI&.](<\\"
670 "^JKLMNOP"
671 "QR-$*);'"
672 "+/STUVWX"
673 "YZ_,%=\"!";
674
675 if (prt_state[prt_unit_num].prtfile == -1)
676 {
677 int rc = openPrtFile (prt_unit_num, buffer, tally);
678 if (rc < 0)
679 {
680 return rc == -3 ? 0 : rc;
681 }
682 }
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713 if (slew == -1)
714 {
715 ssize_t n_write = write (prt_state[prt_unit_num].prtfile, formfeed, 1);
716 if (n_write != 1)
717 {
718 return -2;
719 }
720 }
721 else if (slew)
722 {
723 for (int i = 0; i < slew; i ++)
724 {
725 ssize_t n_write = write (prt_state[prt_unit_num].prtfile, crlf, 2);
726 if (n_write != 2)
727 {
728 return -2;
729 }
730 }
731 }
732
733
734
735
736
737
738 if (tally)
739 {
740 if (isBCD)
741 {
742 uint nchars = tally * 6;
743 #define get_BCD_char(i) ((uint8_t) ((buffer[i / 6] >> ((5 - i % 6) * 6)) & 077))
744
745 if (! is_edited)
746 {
747 uint8 bytes[nchars];
748 for (uint i = 0; i < nchars; i ++)
749 {
750 bytes[i] = (uint8_t) bcd_uc [get_BCD_char (i)];
751 }
752 ssize_t n_write = write (prt_state[prt_unit_num].prtfile, bytes, nchars);
753 if (n_write != nchars)
754 {
755 return -2;
756 }
757 }
758 else
759 {
760
761
762
763
764
765 int BCD_cset = 0;
766 char * table[3] = { bcd, bcd_lc, bcd_uc };
767
768 for (uint i = 0; i < nchars; i ++)
769 {
770 uint8_t ch = get_BCD_char (i);
771
772
773
774
775
776
777
778
779 if (ch == 077)
780 {
781 i ++;
782 uint8_t n = get_BCD_char (i);
783
784 if (n == 077)
785 {
786
787 switch (BCD_cset)
788 {
789 case 0: BCD_cset = 1; break;
790 case 1: BCD_cset = 2; break;
791 case 2: BCD_cset = 1; break;
792 }
793 }
794 else if (n >= 041 && n <= 057)
795 {
796 int nchars = (n - 040) * 8;
797 ssize_t n_write = write (prt_state[prt_unit_num].prtfile, spaces, (size_t)nchars);
798 if (n_write != nchars)
799 {
800 return -2;
801 }
802 }
803 else if (n >= 020 && n <= 022)
804 {
805
806 ssize_t n_write = write (prt_state[prt_unit_num].prtfile, formfeed, 1);
807 if (n_write != 1)
808 {
809 return -2;
810 }
811 }
812 else if (n == 0)
813 {
814 ssize_t n_write = write (prt_state[prt_unit_num].prtfile, cr, 1);
815 if (n_write != 1)
816 {
817 return -2;
818 }
819 }
820 else if (n <= 017)
821 {
822 ssize_t n_write = write (prt_state[prt_unit_num].prtfile, newlines, n);
823 if (n_write != n)
824 {
825 return -2;
826 }
827 }
828 #ifdef TESTING
829 else
830 {
831 sim_warn ("Printer BCD edited ESC %u. %o ignored\n", n, n);
832 }
833 #endif
834 }
835 else
836 {
837 ssize_t n_write = write (prt_state[prt_unit_num].prtfile, table[BCD_cset] + ch, 1);
838 if (n_write != 1)
839 {
840 return -2;
841 }
842 }
843 }
844 }
845 }
846 else
847 {
848 uint nchars = tally * 4;
849 #define get_ASCII_char(i) ((uint8_t) ((buffer[i / 4] >> ((3 - i % 4) * 9)) & 0377))
850
851 if (! is_edited)
852 {
853 uint8 bytes[nchars];
854 uint nbytes = 0;
855 for (uint i = 0; i < nchars; i ++)
856 {
857 uint8_t ch = get_ASCII_char (i);
858 if (isprint (ch))
859 bytes[nbytes ++] = ch;
860 }
861 ssize_t n_write = write (prt_state[prt_unit_num].prtfile, bytes, nbytes);
862 if (n_write != nbytes)
863 {
864 return -2;
865 }
866 }
867 else
868 {
869 uint col = 0;
870 for (uint i = 0; i < tally * 4; i ++)
871 {
872 uint8_t ch = get_ASCII_char (i);
873 if (ch == 037)
874 {
875 i ++;
876 uint8_t n = get_ASCII_char (i);
877 ssize_t n_write = write (prt_state[prt_unit_num].prtfile, spaces, n);
878 if (n_write != n)
879 {
880 return -2;
881 }
882 col += n;
883 }
884 else if (ch == 013)
885 {
886 i ++;
887 uint8_t n = get_ASCII_char (i);
888 if (n)
889 {
890 ssize_t n_write = write (prt_state[prt_unit_num].prtfile, newlines, n);
891 if (n_write != n)
892 {
893 return -2;
894 }
895 }
896 else
897 {
898 ssize_t n_write = write (prt_state[prt_unit_num].prtfile, cr, 1);
899 if (n_write != 1)
900 {
901 return -2;
902 }
903 }
904 col = 0;
905 }
906 else if (ch == 014)
907 {
908 ssize_t n_write = write (prt_state[prt_unit_num].prtfile, formfeed, 1);
909 if (n_write != 1)
910 {
911 return -2;
912 }
913 col = 0;
914 }
915 else if (ch == 011)
916 {
917 i ++;
918 uint8_t n = get_ASCII_char (i);
919 if (col < n)
920 {
921 ssize_t n_write = write (prt_state[prt_unit_num].prtfile, spaces, n - col);
922 if (n_write != n - col)
923 {
924 return -2;
925 }
926 col += n;
927 }
928 }
929 else if (isprint (ch))
930 {
931 ssize_t n_write = write (prt_state[prt_unit_num].prtfile, & ch, 1);
932 if (n_write != 1)
933 {
934 return -2;
935 }
936 col ++;
937 }
938 }
939 }
940 }
941 }
942
943
944 ssize_t n_write = write (prt_state[prt_unit_num].prtfile, cr, 1);
945 if (n_write != 1)
946 {
947 return -2;
948 }
949
950 if ((! isBCD) && eoj (buffer, tally))
951 {
952 close (prt_state[prt_unit_num].prtfile);
953 prt_state[prt_unit_num].prtfile = -1;
954 }
955 return 0;
956 }
957
958 static int loadImageBuffer (uint iom_unit_idx, uint chan)
959 {
960 iom_chan_data_t * p = & iom_chan_data[iom_unit_idx][chan];
961
962 p->stati = 04000;
963 return 0;
964 }
965
966 static int readStatusRegister (uint iom_unit_idx, uint chan)
967 {
968 iom_chan_data_t * p = & iom_chan_data[iom_unit_idx][chan];
969
970 uint tally = p -> DDCW_TALLY;
971
972 if (tally != 4)
973 {
974 sim_warn ("%s: expected tally of 4, is %d\n", __func__, tally);
975 }
976 if (tally == 0)
977 {
978 tally = 4096;
979 }
980
981
982
983 word36 buffer[tally];
984 memset (buffer, 0, sizeof (buffer));
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006 uint wordsProcessed = tally;
1007 iom_indirect_data_service (iom_unit_idx, chan, buffer,
1008 & wordsProcessed, true);
1009 p->charPos = 0;
1010 p->stati = 04000;
1011 return 0;
1012 }
1013
1014 static int loadVFCImage (uint iom_unit_idx, uint chan)
1015 {
1016 iom_chan_data_t * p = & iom_chan_data[iom_unit_idx][chan];
1017
1018 p->stati = 04000;
1019 return 0;
1020 }
1021
1022 static iom_cmd_rc_t print_cmd (uint iom_unit_idx, uint chan, int prt_unit_num, bool isBCD, bool is_edited, int slew)
1023 {
1024 iom_chan_data_t * p = & iom_chan_data[iom_unit_idx][chan];
1025 p->isRead = false;
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061 uint tally = p -> DDCW_TALLY;
1062 sim_debug (DBG_DEBUG, & prt_dev,
1063 "%s: Tally %d (%o)\n", __func__, tally, tally);
1064
1065 if (tally == 0)
1066 tally = 4096;
1067
1068
1069 word36 buffer[tally];
1070 uint wordsProcessed = 0;
1071 iom_indirect_data_service (iom_unit_idx, chan, buffer,
1072 & wordsProcessed, false);
1073 p -> initiate = false;
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094 int rc = print_buf (prt_unit_num, isBCD, is_edited, slew, buffer, tally);
1095 if (rc == -1)
1096 {
1097 p->stati = 04201;
1098 return IOM_CMD_ERROR;
1099 }
1100 if (rc == -2)
1101 {
1102 p->stati = 04210;
1103 return IOM_CMD_ERROR;
1104 }
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116 p -> tallyResidue = 0;
1117 p -> stati = 04000;
1118
1119 return IOM_CMD_RESIDUE;
1120 }
1121
1122 iom_cmd_rc_t prt_cmd_202 (uint iomUnitIdx, uint chan) {
1123 iom_chan_data_t * p = & iom_chan_data[iomUnitIdx][chan];
1124 uint ctlr_unit_idx = get_ctlr_idx (iomUnitIdx, chan);
1125 uint devUnitIdx = cables->urp_to_urd[ctlr_unit_idx][p->IDCW_DEV_CODE].unit_idx;
1126 UNIT * unitp = & prt_unit[devUnitIdx];
1127 int prt_unit_num = (int) PRT_UNIT_NUM (unitp);
1128 prt_state_t * statep = & prt_state[devUnitIdx];
1129
1130
1131 if (IS_IDCW (p)) {
1132
1133 statep->ioMode = prtNoMode;
1134
1135 switch (p->IDCW_DEV_CMD) {
1136 case 000:
1137 sim_debug (DBG_DEBUG, & prt_dev, "%s: Request Status\n", __func__);
1138 p->stati = 04000;
1139 break;
1140
1141 case 010:
1142 sim_debug (DBG_DEBUG, & prt_dev, "%s: Print Nonedited BCD, Slew One Line\n", __func__);
1143 statep->ioMode = prtPrt;
1144 statep->prtUnitNum = prt_unit_num;
1145 statep->isBCD = true;
1146 statep->isEdited = false;
1147 statep->slew = 1;
1148 p->stati = 04000;
1149 break;
1150
1151 case 030:
1152 sim_debug (DBG_DEBUG, & prt_dev, "%s: Print Edited BCD, Slew Zero Lines\n", __func__);
1153 statep->ioMode = prtPrt;
1154 statep->prtUnitNum = prt_unit_num;
1155 statep->isBCD = true;
1156 statep->isEdited = true;
1157 statep->slew = 0;
1158 p->stati = 04000;
1159 break;
1160
1161 case 040:
1162 sim_debug (DBG_DEBUG, & prt_dev, "%s: Reset Status\n", __func__);
1163 p->stati = 04000;
1164 p->isRead = false;
1165 break;
1166
1167 default:
1168 p->stati = 04501;
1169 p->chanStatus = chanStatIncorrectDCW;
1170 if (p->IDCW_DEV_CMD != 051)
1171 sim_warn ("%s: PRT unrecognized device command %02o\n", __func__, p->IDCW_DEV_CMD);
1172 return IOM_CMD_ERROR;
1173 }
1174
1175 sim_debug (DBG_DEBUG, & prt_dev, "%s: stati %04o\n", __func__, p->stati);
1176 return IOM_CMD_PROCEED;
1177 }
1178
1179
1180 switch (statep->ioMode) {
1181 case prtNoMode:
1182
1183
1184
1185 break;
1186
1187 case prtPrt: {
1188 iom_cmd_rc_t rc = print_cmd (iomUnitIdx, chan, statep->prtUnitNum, statep->isBCD,
1189 statep->isEdited, statep->slew);
1190 if (rc)
1191 return rc;
1192 }
1193 break;
1194
1195 default:
1196 sim_warn ("%s: Unrecognized ioMode %d\n", __func__, statep->ioMode);
1197 return IOM_CMD_ERROR;
1198 }
1199
1200 return IOM_CMD_PROCEED;
1201 }
1202
1203 iom_cmd_rc_t prt_cmd_300 (uint iomUnitIdx, uint chan) {
1204 iom_chan_data_t * p = & iom_chan_data[iomUnitIdx][chan];
1205 uint ctlr_unit_idx = get_ctlr_idx (iomUnitIdx, chan);
1206 uint devUnitIdx = cables->urp_to_urd[ctlr_unit_idx][p->IDCW_DEV_CODE].unit_idx;
1207 UNIT * unitp = & prt_unit[devUnitIdx];
1208 int prt_unit_num = (int) PRT_UNIT_NUM (unitp);
1209 prt_state_t * statep = & prt_state[devUnitIdx];
1210
1211
1212 if (IS_IDCW (p)) {
1213
1214 statep->ioMode = prtNoMode;
1215
1216 switch (p->IDCW_DEV_CMD) {
1217
1218 case 000:
1219 sim_debug (DBG_DEBUG, & prt_dev, "%s: Request Status\n", __func__);
1220 p->stati = 04000;
1221 break;
1222
1223 case 011:
1224 sim_debug (DBG_DEBUG, & prt_dev, "%s: Print Nonedited ASCII, Slew One Line\n", __func__);
1225 statep->ioMode = prtPrt;
1226 statep->prtUnitNum = prt_unit_num;
1227 statep->isBCD = false;
1228 statep->isEdited = false;
1229 statep->slew = 1;
1230 p->stati = 04000;
1231 break;
1232
1233 case 014:
1234 sim_debug (DBG_DEBUG, & prt_dev, "%s: Load Image Buffer\n", __func__);
1235 statep->ioMode = prtLdImgBuf;
1236 p->stati = 04000;
1237 break;
1238
1239 case 030:
1240 sim_debug (DBG_DEBUG, & prt_dev, "%s: Print Edited ASCII, Slew Zero Lines\n", __func__);
1241 statep->ioMode = prtPrt;
1242 statep->prtUnitNum = prt_unit_num;
1243 statep->isBCD = false;
1244 statep->isEdited = true;
1245 statep->slew = 0;
1246 p->stati = 04000;
1247 break;
1248
1249 case 040:
1250 sim_debug (DBG_DEBUG, & prt_dev, "%s: Reset Status\n", __func__);
1251 p->stati = 04000;
1252 p->isRead = false;
1253 break;
1254
1255 default:
1256 p->stati = 04501;
1257 p->chanStatus = chanStatIncorrectDCW;
1258 if (p->IDCW_DEV_CMD != 051)
1259 sim_warn ("%s: PRT unrecognized device command %02o\n", __func__, p->IDCW_DEV_CMD);
1260 return IOM_CMD_ERROR;
1261 }
1262
1263 sim_debug (DBG_DEBUG, & prt_dev, "%s: stati %04o\n", __func__, p->stati);
1264 return IOM_CMD_PROCEED;
1265 }
1266
1267
1268 switch (statep->ioMode) {
1269 case prtNoMode:
1270
1271
1272
1273 break;
1274
1275 case prtPrt: {
1276 iom_cmd_rc_t rc = print_cmd (iomUnitIdx, chan, statep->prtUnitNum, statep->isBCD,
1277 statep->isEdited, statep->slew);
1278 if (rc)
1279 return rc;
1280 }
1281 break;
1282
1283 case prtLdImgBuf: {
1284 int rc = loadImageBuffer (iomUnitIdx, chan);
1285 if (rc)
1286 return IOM_CMD_ERROR;
1287 }
1288 break;
1289
1290 default:
1291 sim_warn ("%s: Unrecognized ioMode %d\n", __func__, statep->ioMode);
1292 return IOM_CMD_ERROR;
1293 }
1294 return IOM_CMD_PROCEED;
1295 }
1296
1297 iom_cmd_rc_t prt_cmd_300a (uint iomUnitIdx, uint chan) {
1298 iom_chan_data_t * p = & iom_chan_data[iomUnitIdx][chan];
1299 uint ctlr_unit_idx = get_ctlr_idx (iomUnitIdx, chan);
1300 uint devUnitIdx = cables->urp_to_urd[ctlr_unit_idx][p->IDCW_DEV_CODE].unit_idx;
1301 UNIT * unitp = & prt_unit[devUnitIdx];
1302 int prt_unit_num = (int) PRT_UNIT_NUM (unitp);
1303 prt_state_t * statep = & prt_state[devUnitIdx];
1304
1305
1306 if (IS_IDCW (p)) {
1307
1308 statep->ioMode = prtNoMode;
1309
1310 switch (p->IDCW_DEV_CMD) {
1311 case 000:
1312 sim_debug (DBG_DEBUG, & prt_dev, "%s: Request Status\n", __func__);
1313 p->stati = 04000;
1314 break;
1315
1316 case 001:
1317 sim_debug (DBG_DEBUG, & prt_dev, "%s: Load Image Buffer\n", __func__);
1318 statep->ioMode = prtLdImgBuf;
1319 p->stati = 04000;
1320 break;
1321
1322 case 015:
1323 sim_debug (DBG_DEBUG, & prt_dev, "%s: Print Nonedited ASCII, Slew One Line\n", __func__);
1324 statep->ioMode = prtPrt;
1325 statep->prtUnitNum = prt_unit_num;
1326 statep->isBCD = false;
1327 statep->isEdited = false;
1328 statep->slew = 1;
1329 p->stati = 04000;
1330 break;
1331
1332 case 034:
1333 sim_debug (DBG_DEBUG, & prt_dev, "%s: Print Edited ASCII, Slew Zero Lines\n", __func__);
1334 statep->ioMode = prtPrt;
1335 statep->prtUnitNum = prt_unit_num;
1336 statep->isBCD = false;
1337 statep->isEdited = true;
1338 statep->slew = 0;
1339 p->stati = 04000;
1340 break;
1341
1342 case 040:
1343 sim_debug (DBG_DEBUG, & prt_dev, "%s: Reset Status\n", __func__);
1344 p->stati = 04000;
1345 p->isRead = false;
1346 break;
1347
1348 default:
1349 p->stati = 04501;
1350 p->chanStatus = chanStatIncorrectDCW;
1351 if (p->IDCW_DEV_CMD != 051)
1352 sim_warn ("%s: PRT unrecognized device command %02o\n", __func__, p->IDCW_DEV_CMD);
1353 return IOM_CMD_ERROR;
1354 }
1355
1356 sim_debug (DBG_DEBUG, & prt_dev, "%s: stati %04o\n", __func__, p->stati);
1357 return IOM_CMD_PROCEED;
1358 }
1359
1360
1361 switch (statep->ioMode) {
1362 case prtNoMode:
1363
1364
1365
1366 break;
1367
1368 case prtPrt: {
1369 iom_cmd_rc_t rc = print_cmd (iomUnitIdx, chan, statep->prtUnitNum, statep->isBCD,
1370 statep->isEdited, statep->slew);
1371 if (rc)
1372 return rc;
1373 }
1374 break;
1375
1376 case prtLdImgBuf: {
1377 int rc = loadImageBuffer (iomUnitIdx, chan);
1378 if (rc)
1379 return IOM_CMD_ERROR;
1380 }
1381 break;
1382
1383 default:
1384 sim_warn ("%s: Unrecognized ioMode %d\n", __func__, statep->ioMode);
1385 return IOM_CMD_ERROR;
1386 }
1387 return IOM_CMD_PROCEED;
1388 }
1389
1390 iom_cmd_rc_t prt_cmd_400 (uint iomUnitIdx, uint chan) {
1391 iom_chan_data_t * p = & iom_chan_data[iomUnitIdx][chan];
1392 uint ctlr_unit_idx = get_ctlr_idx (iomUnitIdx, chan);
1393 uint devUnitIdx = cables->urp_to_urd[ctlr_unit_idx][p->IDCW_DEV_CODE].unit_idx;
1394 UNIT * unitp = & prt_unit[devUnitIdx];
1395 int prt_unit_num = (int) PRT_UNIT_NUM (unitp);
1396 prt_state_t * statep = & prt_state[devUnitIdx];
1397
1398
1399 if (IS_IDCW (p)) {
1400
1401 statep->ioMode = prtNoMode;
1402
1403 switch (p->IDCW_DEV_CMD) {
1404
1405 case 000:
1406 sim_debug (DBG_DEBUG, & prt_dev, "%s: Request Status\n", __func__);
1407 p->stati = 04000;
1408 break;
1409
1410 case 001:
1411 sim_debug (DBG_DEBUG, & prt_dev, "%s: Load Image Buffer\n", __func__);
1412 statep->ioMode = prtLdImgBuf;
1413 p->stati = 04000;
1414 break;
1415
1416 case 003:
1417 sim_debug (DBG_DEBUG, & prt_dev, "%s: Load Image Buffer\n", __func__);
1418 statep->ioMode = prtRdStatReg;
1419 p->stati = 04000;
1420 break;
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446 case 005:
1447 sim_debug (DBG_DEBUG, & prt_dev, "%s: Load VFC Image\n", __func__);
1448 statep->ioMode = prtLdVFCImg;
1449 p->stati = 04000;
1450 break;
1451
1452 case 010:
1453 sim_debug (DBG_DEBUG, & prt_dev, "%s: Print Nonedited BCD, Slew Zero Lines\n", __func__);
1454 statep->ioMode = prtPrt;
1455 statep->prtUnitNum = prt_unit_num;
1456 statep->isBCD = true;
1457 statep->isEdited = false;
1458 statep->slew = 0;
1459 p->stati = 04000;
1460 break;
1461
1462 case 011:
1463 sim_debug (DBG_DEBUG, & prt_dev, "%s: Print Nonedited BCD, Slew One Line\n", __func__);
1464 statep->ioMode = prtPrt;
1465 statep->prtUnitNum = prt_unit_num;
1466 statep->isBCD = true;
1467 statep->isEdited = false;
1468 statep->slew = 1;
1469 p->stati = 04000;
1470 break;
1471
1472 case 012:
1473 sim_debug (DBG_DEBUG, & prt_dev, "%s: Print Nonedited BCD, Slew Two Lines\n", __func__);
1474 statep->ioMode = prtPrt;
1475 statep->prtUnitNum = prt_unit_num;
1476 statep->isBCD = true;
1477 statep->isEdited = false;
1478 statep->slew = 2;
1479 p->stati = 04000;
1480 break;
1481
1482 case 013:
1483 sim_debug (DBG_DEBUG, & prt_dev, "%s: Print Nonedited BCD, Slew Top Of Page\n", __func__);
1484 statep->ioMode = prtPrt;
1485 statep->prtUnitNum = prt_unit_num;
1486 statep->isBCD = true;
1487 statep->isEdited = false;
1488 statep->slew = -1;
1489 p->stati = 04000;
1490 break;
1491
1492 case 014:
1493 sim_debug (DBG_DEBUG, & prt_dev, "%s: Print Nonedited ASCII, Slew Zero Lines\n", __func__);
1494 statep->ioMode = prtPrt;
1495 statep->prtUnitNum = prt_unit_num;
1496 statep->isBCD = false;
1497 statep->isEdited = false;
1498 statep->slew = 0;
1499 p->stati = 04000;
1500 break;
1501
1502 case 015:
1503 sim_debug (DBG_DEBUG, & prt_dev, "%s: Print Nonedited ASCII, Slew One Line\n", __func__);
1504 statep->ioMode = prtPrt;
1505 statep->prtUnitNum = prt_unit_num;
1506 statep->isBCD = false;
1507 statep->isEdited = false;
1508 statep->slew = 1;
1509 p->stati = 04000;
1510 break;
1511
1512 case 016:
1513 sim_debug (DBG_DEBUG, & prt_dev, "%s: Print Nonedited ASCII, Slew Two Lines\n", __func__);
1514 statep->ioMode = prtPrt;
1515 statep->prtUnitNum = prt_unit_num;
1516 statep->isBCD = false;
1517 statep->isEdited = false;
1518 statep->slew = 2;
1519 p->stati = 04000;
1520 break;
1521
1522 case 017:
1523 sim_debug (DBG_DEBUG, & prt_dev, "%s: Print Nonedited ASCII, Slew Top Of Page\n", __func__);
1524 statep->ioMode = prtPrt;
1525 statep->prtUnitNum = prt_unit_num;
1526 statep->isBCD = false;
1527 statep->isEdited = false;
1528 statep->slew = -1;
1529 p->stati = 04000;
1530 break;
1531
1532 case 030:
1533 sim_debug (DBG_DEBUG, & prt_dev, "%s: Print Edited BCD, Slew Zero Lines\n", __func__);
1534 statep->ioMode = prtPrt;
1535 statep->prtUnitNum = prt_unit_num;
1536 statep->isBCD = true;
1537 statep->isEdited = true;
1538 statep->slew = 0;
1539 p->stati = 04000;
1540 break;
1541
1542 case 031:
1543 sim_debug (DBG_DEBUG, & prt_dev, "%s: Print Edited BCD, Slew One Line\n", __func__);
1544 statep->ioMode = prtPrt;
1545 statep->prtUnitNum = prt_unit_num;
1546 statep->isBCD = true;
1547 statep->isEdited = true;
1548 statep->slew = 1;
1549 p->stati = 04000;
1550 break;
1551
1552 case 032:
1553 sim_debug (DBG_DEBUG, & prt_dev, "%s: Print Edited BCD, Slew Two Lines\n", __func__);
1554 statep->ioMode = prtPrt;
1555 statep->prtUnitNum = prt_unit_num;
1556 statep->isBCD = true;
1557 statep->isEdited = true;
1558 statep->slew = 2;
1559 p->stati = 04000;
1560 break;
1561
1562 case 033:
1563 sim_debug (DBG_DEBUG, & prt_dev, "%s: Print Edited BCD, Slew Top Of Page\n", __func__);
1564 statep->ioMode = prtPrt;
1565 statep->prtUnitNum = prt_unit_num;
1566 statep->isBCD = true;
1567 statep->isEdited = true;
1568 statep->slew = -1;
1569 p->stati = 04000;
1570 break;
1571
1572 case 034:
1573 sim_debug (DBG_DEBUG, & prt_dev, "%s: Print Edited ASCII, Slew Zero Lines\n", __func__);
1574 statep->ioMode = prtPrt;
1575 statep->prtUnitNum = prt_unit_num;
1576 statep->isBCD = false;
1577 statep->isEdited = true;
1578 statep->slew = 0;
1579 p->stati = 04000;
1580 break;
1581
1582 case 035:
1583 sim_debug (DBG_DEBUG, & prt_dev, "%s: Print Edited ASCII, Slew One Line\n", __func__);
1584 statep->ioMode = prtPrt;
1585 statep->prtUnitNum = prt_unit_num;
1586 statep->isBCD = false;
1587 statep->isEdited = true;
1588 statep->slew = 1;
1589 p->stati = 04000;
1590 break;
1591
1592 case 036:
1593 sim_debug (DBG_DEBUG, & prt_dev, "%s: Print Edited ASCII, Slew Two Lines\n", __func__);
1594 statep->ioMode = prtPrt;
1595 statep->prtUnitNum = prt_unit_num;
1596 statep->isBCD = false;
1597 statep->isEdited = true;
1598 statep->slew = 2;
1599 p->stati = 04000;
1600 break;
1601
1602 case 037:
1603 sim_debug (DBG_DEBUG, & prt_dev, "%s: Print Edited ASCII, Slew Top Of Page\n", __func__);
1604 statep->ioMode = prtPrt;
1605 statep->prtUnitNum = prt_unit_num;
1606 statep->isBCD = false;
1607 statep->isEdited = true;
1608 statep->slew = -1;
1609 p->stati = 04000;
1610 break;
1611
1612 case 040:
1613 sim_debug (DBG_DEBUG, & prt_dev, "%s: Reset Status\n", __func__);
1614 p->stati = 04000;
1615 p->isRead = false;
1616 break;
1617
1618 case 061: {
1619 sim_debug (DBG_DEBUG, & prt_dev, "%s: Slew One Line\n", __func__);
1620 int rc = print_buf (prt_unit_num, false, false, 1, NULL, 0);
1621 if (rc == -1) {
1622 p->stati = 04201;
1623 return IOM_CMD_ERROR;
1624 }
1625 if (rc == -2) {
1626 p->stati = 04210;
1627 return IOM_CMD_ERROR;
1628 }
1629 p->stati = 04000;
1630 p->isRead = false;
1631 }
1632 break;
1633
1634 case 062: {
1635 sim_debug (DBG_DEBUG, & prt_dev, "%s: Slew Two Lines\n", __func__);
1636 int rc = print_buf (prt_unit_num, false, false, 2, NULL, 0);
1637 if (rc == -1) {
1638 p->stati = 04201;
1639 return IOM_CMD_ERROR;
1640 }
1641 if (rc == -2) {
1642 p->stati = 04210;
1643 return IOM_CMD_ERROR;
1644 }
1645 p->stati = 04000;
1646 p->isRead = false;
1647 }
1648 break;
1649
1650 case 063: {
1651 sim_debug (DBG_DEBUG, & prt_dev, "%s: Slew To Top Of Page\n", __func__);
1652 int rc = print_buf (prt_unit_num, false, false, -1, NULL, 0);
1653 if (rc == -1) {
1654 p->stati = 04201;
1655 return IOM_CMD_ERROR;
1656 }
1657 if (rc == -2) {
1658 p->stati = 04210;
1659 return IOM_CMD_ERROR;
1660 }
1661 p->stati = 04000;
1662 p->isRead = false;
1663 }
1664 break;
1665
1666 case 066:
1667 sim_debug (DBG_DEBUG, & prt_dev, "%s: Reserve Device\n", __func__);
1668 p->stati = 04000;
1669 p->isRead = false;
1670 break;
1671
1672 case 067:
1673 sim_debug (DBG_DEBUG, & prt_dev, "%s: Release Device\n", __func__);
1674 p->stati = 04000;
1675 p->isRead = false;
1676 break;
1677
1678 default:
1679 p->stati = 04501;
1680 p->chanStatus = chanStatIncorrectDCW;
1681 if (p->IDCW_DEV_CMD != 051)
1682 sim_warn ("%s: PRT unrecognized device command %02o\n", __func__, p->IDCW_DEV_CMD);
1683 return IOM_CMD_ERROR;
1684 }
1685
1686 sim_debug (DBG_DEBUG, & prt_dev, "%s: stati %04o\n", __func__, p->stati);
1687 return IOM_CMD_PROCEED;
1688 }
1689
1690
1691 switch (statep->ioMode) {
1692 case prtNoMode:
1693
1694
1695
1696 break;
1697
1698 case prtPrt: {
1699 iom_cmd_rc_t rc = print_cmd (iomUnitIdx, chan, statep->prtUnitNum, statep->isBCD,
1700 statep->isEdited, statep->slew);
1701 if (rc)
1702 return rc;
1703 }
1704 break;
1705
1706 case prtLdImgBuf: {
1707 int rc = loadImageBuffer (iomUnitIdx, chan);
1708 if (rc)
1709 return IOM_CMD_ERROR;
1710 }
1711 break;
1712
1713 case prtRdStatReg: {
1714 int rc = readStatusRegister (iomUnitIdx, chan);
1715 if (rc)
1716 return IOM_CMD_ERROR;
1717 }
1718 break;
1719
1720 case prtLdVFCImg: {
1721 int rc = loadVFCImage (iomUnitIdx, chan);
1722 if (rc)
1723 return IOM_CMD_ERROR;
1724 }
1725 break;
1726
1727 default:
1728 sim_warn ("%s: Unrecognized ioMode %d\n", __func__, statep->ioMode);
1729 return IOM_CMD_ERROR;
1730 }
1731 return IOM_CMD_PROCEED;
1732 }
1733
1734 iom_cmd_rc_t prt_iom_cmd (uint iomUnitIdx, uint chan) {
1735 iom_chan_data_t * p = & iom_chan_data[iomUnitIdx][chan];
1736 uint ctlr_unit_idx = get_ctlr_idx (iomUnitIdx, chan);
1737 uint devUnitIdx = cables->urp_to_urd[ctlr_unit_idx][p->IDCW_DEV_CODE].unit_idx;
1738 UNIT * unitp = & prt_unit[devUnitIdx];
1739 int prt_unit_num = (int) PRT_UNIT_NUM (unitp);
1740
1741 switch (model_type [prt_state[prt_unit_num].model]) {
1742 case 1:
1743 return prt_cmd_202 (iomUnitIdx, chan);
1744
1745 case 2:
1746 return prt_cmd_300 (iomUnitIdx, chan);
1747
1748 case 3:
1749 return prt_cmd_300a (iomUnitIdx, chan);
1750
1751
1752 case 4:
1753 return prt_cmd_400 (iomUnitIdx, chan);
1754 }
1755 p->stati = 04502;
1756 return IOM_CMD_DISCONNECT;
1757 }
1758
1759 static t_stat prt_show_nunits (UNUSED FILE * st, UNUSED UNIT * uptr, UNUSED int val,
1760 UNUSED const void * desc)
1761 {
1762 sim_printf("Number of PRT units in system is %d\n", prt_dev.numunits);
1763 return SCPE_OK;
1764 }
1765
1766 static t_stat prt_set_nunits (UNUSED UNIT * uptr, UNUSED int32 value, const char * cptr,
1767 UNUSED void * desc)
1768 {
1769 if (! cptr)
1770 return SCPE_ARG;
1771 int n = atoi (cptr);
1772 if (n < 1 || n > N_PRT_UNITS_MAX)
1773 return SCPE_ARG;
1774 prt_dev.numunits = (uint) n;
1775 return SCPE_OK;
1776 }
1777
1778 static t_stat prt_show_device_name (UNUSED FILE * st, UNIT * uptr,
1779 UNUSED int val, UNUSED const void * desc)
1780 {
1781 int n = (int) PRT_UNIT_NUM (uptr);
1782 if (n < 0 || n >= N_PRT_UNITS_MAX)
1783 return SCPE_ARG;
1784 sim_printf("name : %s", prt_state[n].device_name);
1785 return SCPE_OK;
1786 }
1787
1788 static t_stat prt_set_device_model (UNUSED UNIT * uptr, UNUSED int32 value,
1789 const UNUSED char * cptr, UNUSED void * desc)
1790 {
1791 int n = (int) PRT_UNIT_NUM (uptr);
1792 if (n < 0 || n >= N_PRT_UNITS_MAX)
1793 return SCPE_ARG;
1794 if (cptr)
1795 {
1796 for (int i = 0; i < N_MODELS; i ++)
1797 {
1798 if (strcmp (cptr, model_names[i]) == 0)
1799 {
1800 prt_state[n].model = i;
1801 return SCPE_OK;
1802 }
1803 }
1804 sim_printf ("Model '%s' not known (202 300 301 302 303 304 401 402 901 1000 1200 1201 1600)\n", cptr);
1805 return SCPE_ARG;
1806 }
1807 sim_printf ("Specify model from 202 300 301 302 303 304 401 402 901 1000 1200 1201 1600\n");
1808 return SCPE_ARG;
1809 }
1810
1811 static t_stat prt_show_device_model (UNUSED FILE * st, UNIT * uptr,
1812 UNUSED int val, UNUSED const void * desc)
1813 {
1814 int n = (int) PRT_UNIT_NUM (uptr);
1815 if (n < 0 || n >= N_PRT_UNITS_MAX)
1816 return SCPE_ARG;
1817 sim_printf("model : %s", model_names[prt_state[n].model]);
1818 return SCPE_OK;
1819 }
1820
1821 static t_stat prt_set_device_name (UNUSED UNIT * uptr, UNUSED int32 value,
1822 const UNUSED char * cptr, UNUSED void * desc)
1823 {
1824 int n = (int) PRT_UNIT_NUM (uptr);
1825 if (n < 0 || n >= N_PRT_UNITS_MAX)
1826 return SCPE_ARG;
1827 if (cptr)
1828 {
1829 strncpy (prt_state[n].device_name, cptr, MAX_DEV_NAME_LEN - 1);
1830 prt_state[n].device_name[MAX_DEV_NAME_LEN - 1] = 0;
1831 }
1832 else
1833 {
1834 prt_state[n].device_name[0] = 0;
1835 }
1836 return SCPE_OK;
1837 }
1838
1839 static t_stat prt_show_path (UNUSED FILE * st, UNUSED UNUSED UNIT * uptr,
1840 UNUSED int val, UNUSED const void * desc)
1841 {
1842 if (prt_path[1] != '\0')
1843 {
1844 sim_printf("Path to PRT files is %s\n", prt_path);
1845 }
1846 else
1847 {
1848 char cwd_path[PATH_MAX+1];
1849 if (getcwd(cwd_path, sizeof(cwd_path)) != NULL)
1850 {
1851 sim_printf("Path to PRT files is %s\n", cwd_path);
1852 }
1853 else
1854 {
1855 if (errno)
1856 {
1857 sim_printf("Path to PRT files is unavailable (%s)\n",
1858 strerror(errno));
1859 }
1860 else
1861 {
1862 sim_printf("Path to PRT files is undefined\n");
1863 }
1864 }
1865 }
1866 return SCPE_OK;
1867 }
1868
1869 static t_stat prt_set_path (UNUSED UNIT * uptr, UNUSED int32 value,
1870 const UNUSED char * cptr, UNUSED void * desc)
1871 {
1872 if (! cptr)
1873 return SCPE_ARG;
1874
1875 size_t len = strlen(cptr);
1876
1877 if (len >= sizeof(prt_path))
1878 return SCPE_ARG;
1879 strncpy(prt_path, cptr, sizeof(prt_path));
1880 if (len > 0)
1881 {
1882 if (prt_path[len - 1] != '/')
1883 {
1884 if (len == sizeof(prt_path) - 1)
1885 return SCPE_ARG;
1886 prt_path[len++] = '/';
1887 prt_path[len] = 0;
1888 }
1889 }
1890 return SCPE_OK;
1891 }
1892
1893 t_stat burst_printer (UNUSED int32 arg, const char * buf)
1894 {
1895 for (int i = 0; i < N_PRT_UNITS_MAX; i ++)
1896 {
1897 if (strcmp (buf, prt_state[i].device_name) == 0)
1898 {
1899 if (prt_state[i].prtfile != -1)
1900 {
1901 close (prt_state[i].prtfile);
1902 prt_state[i].prtfile = -1;
1903 return SCPE_OK;
1904 }
1905 sim_printf ("burst sees nothing to burst\n");
1906 return SCPE_OK;
1907 }
1908 }
1909 sim_printf ("burst can't find printer named '%s'\n", buf);
1910 return SCPE_ARG;
1911 }
1912
1913 static t_stat signal_prt_ready (uint prt_unit_idx) {
1914
1915 if (! sim_is_running)
1916 return SCPE_OK;
1917 uint ctlr_unit_idx = cables->prt_to_urp[prt_unit_idx].ctlr_unit_idx;
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942 for (uint ctlr_port_num = 0; ctlr_port_num < MAX_CTLR_PORTS; ctlr_port_num ++) {
1943 struct ctlr_to_iom_s * urp_to_iom = & cables->urp_to_iom[ctlr_unit_idx][ctlr_port_num];
1944 if (urp_to_iom->in_use) {
1945 uint iom_unit_idx = urp_to_iom->iom_unit_idx;
1946 uint chan_num = urp_to_iom->chan_num;
1947 uint dev_code = cables->prt_to_urp[prt_unit_idx].dev_code;
1948
1949 send_special_interrupt (iom_unit_idx, chan_num, dev_code, 0x40, 01 );
1950 return SCPE_OK;
1951 }
1952 }
1953 return SCPE_ARG;
1954
1955 }
1956
1957 static t_stat prt_set_ready (UNIT * uptr, UNUSED int32 value,
1958 UNUSED const char * cptr,
1959 UNUSED void * desc)
1960 {
1961 int n = (int) PRT_UNIT_NUM (uptr);
1962 if (n < 0 || n >= N_PRT_UNITS_MAX)
1963 {
1964 sim_debug (DBG_ERR, & prt_dev,
1965 "Printer set ready: Invalid unit number %ld\n", (long) n);
1966 sim_printf ("error: Invalid unit number %ld\n", (long) n);
1967 return SCPE_ARG;
1968 }
1969 return signal_prt_ready ((uint) n);
1970 }
1971
1972 static config_value_list_t cfg_on_off[] =
1973 {
1974 { "off", 0 },
1975 { "on", 1 },
1976 { "disable", 0 },
1977 { "enable", 1 },
1978 { NULL, 0 }
1979 };
1980
1981 static config_list_t prt_config_list[] =
1982 {
1983 { "split", 0, 1, cfg_on_off },
1984 { NULL, 0, 0, NULL }
1985 };
1986
1987 static t_stat prt_set_config (UNUSED UNIT * uptr, UNUSED int32 value,
1988 const char * cptr, UNUSED void * desc)
1989 {
1990 int devUnitIdx = (int) PRT_UNIT_NUM (uptr);
1991 prt_state_t * psp = prt_state + devUnitIdx;
1992
1993 config_state_t cfg_state = { NULL, NULL };
1994
1995 for (;;)
1996 {
1997 int64_t v;
1998 int rc = cfg_parse (__func__, cptr, prt_config_list,
1999 & cfg_state, & v);
2000 if (rc == -1)
2001 break;
2002
2003 if (rc == -2)
2004 {
2005 cfg_parse_done (& cfg_state);
2006 return SCPE_ARG;
2007 }
2008 const char * p = prt_config_list[rc].name;
2009
2010 if (strcmp (p, "split") == 0)
2011 {
2012 psp->split = v != 0;
2013 continue;
2014 }
2015
2016 sim_warn ("error: prt_set_config: Invalid cfg_parse rc <%ld>\n",
2017 (long) rc);
2018 cfg_parse_done (& cfg_state);
2019 return SCPE_ARG;
2020 }
2021 cfg_parse_done (& cfg_state);
2022 return SCPE_OK;
2023 }
2024
2025 static t_stat prt_show_config (UNUSED FILE * st, UNUSED UNIT * uptr,
2026 UNUSED int val, UNUSED const void * desc)
2027 {
2028 int devUnitIdx = (int) PRT_UNIT_NUM (uptr);
2029 prt_state_t * psp = prt_state + devUnitIdx;
2030 sim_msg ("split : %d", psp->split);
2031 return SCPE_OK;
2032 }