This source file includes following definitions.
- get_Cr
- op_desc_str
- do_ITP
- do_ITS
- do_ITS_ITP
- updateIWB
- do_caf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 #include <stdio.h>
23 #include "dps8.h"
24 #include "dps8_addrmods.h"
25 #include "dps8_sys.h"
26 #include "dps8_faults.h"
27 #include "dps8_scu.h"
28 #include "dps8_iom.h"
29 #include "dps8_cable.h"
30 #include "dps8_cpu.h"
31 #include "dps8_append.h"
32 #include "dps8_ins.h"
33 #include "dps8_iefp.h"
34 #include "dps8_opcodetable.h"
35 #include "dps8_utils.h"
36 #if defined(THREADZ) || defined(LOCKLESS)
37 # include "threadz.h"
38 #endif
39
40 #define DBG_CTR cpu.cycleCnt
41
42
43
44
45
46
47
48 static word18 get_Cr (word4 Tdes)
49 {
50 cpu.ou.directOperandFlag = false;
51
52 if (Tdes == TD_N)
53 return 0;
54
55 if (Tdes & 010)
56 return cpu.rX [X (Tdes)];
57
58 switch (Tdes)
59 {
60 case TD_N:
61 return 0;
62
63 case TD_AU:
64 #ifdef TESTING
65 HDBGRegAR ("au");
66 #endif
67 return GETHI (cpu.rA);
68
69 case TD_QU:
70 #ifdef TESTING
71 HDBGRegAR ("qu");
72 #endif
73 return GETHI (cpu.rQ);
74
75 case TD_DU:
76 cpu.ou.directOperand = 0;
77 SETHI (cpu.ou.directOperand, cpu.rY);
78 cpu.ou.directOperandFlag = true;
79
80 sim_debug (DBG_ADDRMOD, & cpu_dev,
81 "%s(TD_DU): rY=%06o directOperand=%012"PRIo64"\n",
82 __func__, cpu.rY, cpu.ou.directOperand);
83
84 return 0;
85
86 case TD_IC:
87 return cpu.PPR.IC;
88
89 case TD_AL:
90 #ifdef TESTING
91 HDBGRegAR ("al");
92 #endif
93 return GETLO (cpu.rA);
94
95 case TD_QL:
96 #ifdef TESTING
97 HDBGRegAR ("ql");
98 #endif
99 return GETLO (cpu.rQ);
100
101 case TD_DL:
102 cpu.ou.directOperand = 0;
103 SETLO (cpu.ou.directOperand, cpu.rY);
104 cpu.ou.directOperandFlag = true;
105
106 sim_debug (DBG_ADDRMOD, & cpu_dev,
107 "%s(TD_DL): rY=%06o directOperand=%012"PRIo64"\n",
108 __func__, cpu.rY, cpu.ou.directOperand);
109
110 return 0;
111 }
112 return 0;
113 }
114
115 static char * op_desc_str (char * temp)
116 {
117 DCDstruct * i = & cpu.currentInstruction;
118
119 strcpy (temp, "");
120
121 if (READOP (i))
122 {
123 switch (operand_size ())
124 {
125 case 1:
126 strcat (temp, "readCY");
127 break;
128
129 case 2:
130 strcat (temp, "readCYpair2");
131 break;
132
133 case 8:
134 strcat (temp, "readCYblock8");
135 break;
136
137 case 16:
138 strcat (temp, "readCYblock16");
139 break;
140
141 case 32:
142 strcat (temp, "readCYblock32");
143 break;
144 }
145 }
146
147 if (WRITEOP (i))
148 {
149 if (strlen (temp))
150 strcat (temp, "/");
151
152 switch (operand_size ())
153 {
154 case 1:
155 strcat (temp, "writeCY");
156 break;
157
158 case 2:
159 strcat (temp, "writeCYpair2");
160 break;
161
162 case 8:
163 strcat (temp, "writeCYblock8");
164 break;
165
166 case 16:
167 strcat (temp, "writeCYblock16");
168 break;
169
170 case 32:
171 strcat (temp, "writeCYblock32");
172 break;
173 }
174 }
175
176 if (TRANSOP (i))
177 {
178 if (strlen (temp))
179 strcat (temp, "/");
180
181 strcat (temp, "prepareCA (TRA)");
182 }
183
184 if (! READOP (i) && ! WRITEOP (i) && ! TRANSOP (i) &&
185 i -> info -> flags & PREPARE_CA)
186 {
187 if (strlen (temp))
188 strcat (temp, "/");
189
190 strcat (temp, "prepareCA");
191 }
192
193 return temp;
194 }
195
196 static void do_ITP (void)
197 {
198 sim_debug (DBG_APPENDING, & cpu_dev,
199 "ITP Pair: PRNUM=%o BITNO=%o WORDNO=%o MOD=%o\n",
200 GET_ITP_PRNUM (cpu.itxPair), GET_ITP_WORDNO (cpu.itxPair),
201 GET_ITP_BITNO (cpu.itxPair), GET_ITP_MOD (cpu.itxPair));
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219 word3 n = GET_ITP_PRNUM (cpu.itxPair);
220 CPTUR (cptUsePRn + n);
221 #ifdef TESTING
222 HDBGRegPRR (n, "ITP");
223 #endif
224 cpu.TPR.TSR = cpu.PR[n].SNR;
225 cpu.TPR.TRR = max3 (cpu.PR[n].RNR, cpu.RSDWH_R1, cpu.TPR.TRR);
226 cpu.TPR.TBR = GET_ITP_BITNO (cpu.itxPair);
227 cpu.TPR.CA = cpu.PAR[n].WORDNO + GET_ITP_WORDNO (cpu.itxPair);
228 cpu.TPR.CA &= AMASK;
229 cpu.rY = cpu.TPR.CA;
230
231 cpu.rTAG = GET_ITP_MOD (cpu.itxPair);
232
233 cpu.cu.itp = 1;
234 cpu.cu.TSN_PRNO[0] = n;
235 cpu.cu.TSN_VALID[0] = 1;
236
237 return;
238 }
239
240 static void do_ITS (void)
241 {
242 sim_debug (DBG_APPENDING, & cpu_dev,
243 "ITS Pair: SEGNO=%o RN=%o WORDNO=%o BITNO=%o MOD=%o\n",
244 GET_ITS_SEGNO (cpu.itxPair), GET_ITS_RN (cpu.itxPair),
245 GET_ITS_WORDNO (cpu.itxPair), GET_ITS_BITNO (cpu.itxPair),
246 GET_ITS_MOD (cpu.itxPair));
247
248
249
250
251
252
253
254
255
256
257
258
259
260 cpu.TPR.TSR = GET_ITS_SEGNO (cpu.itxPair);
261
262 sim_debug (DBG_APPENDING, & cpu_dev,
263 "ITS Pair Ring: RN %o RSDWH_R1 %o TRR %o max %o\n",
264 GET_ITS_RN (cpu.itxPair), cpu.RSDWH_R1, cpu.TPR.TRR,
265 max3 (GET_ITS_RN (cpu.itxPair), cpu.RSDWH_R1, cpu.TPR.TRR));
266
267 cpu.TPR.TRR = max3 (GET_ITS_RN (cpu.itxPair), cpu.RSDWH_R1, cpu.TPR.TRR);
268 cpu.TPR.TBR = GET_ITS_BITNO (cpu.itxPair);
269 cpu.TPR.CA = GET_ITS_WORDNO (cpu.itxPair);
270 cpu.TPR.CA &= AMASK;
271
272 cpu.rY = cpu.TPR.CA;
273
274 cpu.rTAG = GET_ITS_MOD (cpu.itxPair);
275
276 cpu.cu.its = 1;
277
278 return;
279 }
280
281
282 static void do_ITS_ITP (void)
283 {
284 word6 ind_tag = GET_TAG (cpu.itxPair [0]);
285
286 sim_debug (DBG_APPENDING, & cpu_dev,
287 "do_ITS/ITP: %012"PRIo64" %012"PRIo64"\n",
288 cpu.itxPair[0], cpu.itxPair[1]);
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311 if (ISITS (ind_tag))
312 do_ITS ();
313 else
314 do_ITP ();
315
316
317 cpu.cu.XSF = 1;
318 sim_debug (DBG_APPENDING, & cpu_dev, "do_ITS_ITP sets XSF to 1\n");
319 }
320
321 void updateIWB (word18 addr, word6 tag)
322 {
323 word36 * wb;
324 if (USE_IRODD)
325 wb = & cpu.cu.IRODD;
326 else
327 wb = & cpu.cu.IWB;
328 sim_debug (DBG_ADDRMOD, & cpu_dev,
329 "updateIWB: IWB was %012"PRIo64" %06o %s\n",
330 * wb, GET_ADDR (* wb),
331 extMods [GET_TAG (* wb)].mod);
332
333 putbits36_18 (wb, 0, addr);
334 putbits36_6 (wb, 30, tag);
335 putbits36_1 (wb, 29, 0);
336
337 sim_debug (DBG_ADDRMOD, & cpu_dev,
338 "updateIWB: IWB now %012"PRIo64" %06o %s\n",
339 * wb, GET_ADDR (* wb),
340 extMods [GET_TAG (* wb)].mod);
341
342 decode_instruction (IWB_IRODD, & cpu.currentInstruction);
343 }
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360 void do_caf (void)
361 {
362 if (cpu.currentInstruction.b29 == 0)
363 {
364 cpu.TPR.CA = GET_ADDR (IWB_IRODD);
365 }
366 else
367 {
368 word3 n = GET_PRN(IWB_IRODD);
369 #ifdef TESTING
370 HDBGRegPRR (n, "b29");
371 #endif
372 word15 offset = GET_OFFSET(IWB_IRODD);
373 cpu.TPR.CA = (cpu.PAR[n].WORDNO + SIGNEXT15_18 (offset))
374 & MASK18;
375 }
376 char buf [256];
377 sim_debug (DBG_ADDRMOD, & cpu_dev,
378 "%s(Entry): operType:%s TPR.CA=%06o\n",
379 __func__, op_desc_str (buf), cpu.TPR.CA);
380 sim_debug (DBG_ADDRMOD, & cpu_dev,
381 "%s(Entry): CT_HOLD %o\n",
382 __func__, cpu.cu.CT_HOLD);
383
384 DCDstruct * i = & cpu.currentInstruction;
385
386 word6 Tm = 0;
387 word6 Td = 0;
388
389
390
391 cpu.ou.directOperandFlag = false;
392
393 if (i -> info -> flags & NO_TAG)
394 cpu.rTAG = 0;
395 else
396 cpu.rTAG = GET_TAG (IWB_IRODD);
397
398 int lockupCnt = 0;
399 #define lockupLimit 4096
400
401 startCA:;
402
403 if (++ lockupCnt > lockupLimit)
404 {
405 doFault (FAULT_LUF, fst_zero, "Lockup in addrmod");
406 }
407
408 Td = GET_TD (cpu.rTAG);
409 Tm = GET_TM (cpu.rTAG);
410
411
412
413
414 if (cpu.cu.CT_HOLD)
415 {
416 sim_debug (DBG_ADDRMOD, & cpu_dev,
417 "%s(startCA): restart; CT_HOLD %02o\n",
418 __func__, cpu.cu.CT_HOLD);
419
420 if (cpu.tweaks.isolts_mode &&
421 GET_TM(cpu.cu.CT_HOLD) == TM_IT && GET_TD (cpu.cu.CT_HOLD) == IT_DIC &&
422 cpu.cu.pot == 1 && GET_ADDR (IWB_IRODD) == cpu.TPR.CA)
423 {
424 cpu.TPR.CA--;
425 sim_warn ("%s: correct CA\n", __func__);
426 }
427 if (Tm == TM_IT && (Td == IT_IDC || Td == IT_DIC))
428 {
429 cpu.cu.pot = 1;
430 }
431 }
432 else
433 {
434
435 cpu.cu.its = 0;
436 cpu.cu.itp = 0;
437 cpu.cu.pot = 0;
438 }
439 sim_debug (DBG_ADDRMOD, & cpu_dev,
440 "%s(startCA): TAG=%02o(%s) Tm=%o Td=%o CT_HOLD %02o\n",
441 __func__, cpu.rTAG, get_mod_string (buf, cpu.rTAG), Tm, Td, cpu.cu.CT_HOLD);
442
443 switch (Tm)
444 {
445 case TM_R:
446 goto R_MOD;
447 case TM_RI:
448 goto RI_MOD;
449 case TM_IT:
450 goto IT_MOD;
451 case TM_IR:
452 goto IR_MOD;
453 default:
454 break;
455 }
456
457 sim_printf ("%s(startCA): unknown Tm??? %o\n",
458 __func__, GET_TM (cpu.rTAG));
459 sim_warn ("(startCA): unknown Tmi; can't happen!\n");
460 return;
461
462
463 R_MOD:;
464 {
465 if (Td == TD_N)
466 {
467
468 return;
469 }
470
471 word18 Cr = get_Cr (Td);
472
473 sim_debug (DBG_ADDRMOD, & cpu_dev, "R_MOD: Cr=%06o\n", Cr);
474
475 if (cpu.ou.directOperandFlag)
476 {
477 sim_debug (DBG_ADDRMOD, & cpu_dev,
478 "R_MOD: directOperand = %012"PRIo64"\n",
479 cpu.ou.directOperand);
480 return;
481 }
482
483
484
485 if (cpu.cu.rpt || cpu.cu.rd | cpu.cu.rl)
486 {
487 if (cpu.currentInstruction.b29)
488 {
489 word3 PRn = GET_PRN(IWB_IRODD);
490 #ifdef TESTING
491 HDBGRegPRR (PRn, "rpx b29");
492 #endif
493 CPTUR (cptUsePRn + PRn);
494 cpu.TPR.CA = Cr + cpu.PR [PRn].WORDNO;
495 cpu.TPR.CA &= AMASK;
496 }
497 else
498 {
499 cpu.TPR.CA = Cr;
500 }
501 }
502 else
503 {
504 cpu.TPR.CA += Cr;
505 cpu.TPR.CA &= MASK18;
506 }
507 sim_debug (DBG_ADDRMOD, & cpu_dev, "R_MOD: TPR.CA=%06o\n",
508 cpu.TPR.CA);
509
510 return;
511 }
512
513
514 RI_MOD:;
515 {
516 sim_debug (DBG_ADDRMOD, & cpu_dev, "RI_MOD: Td=%o\n", Td);
517
518 if (Td == TD_DU || Td == TD_DL)
519 doFault (FAULT_IPR, fst_ill_mod,
520 "RI_MOD: Td == TD_DU || Td == TD_DL");
521
522 if (Td != TD_N)
523 {
524 word18 Cr = get_Cr (Td);
525
526
527
528
529 sim_debug (DBG_ADDRMOD, & cpu_dev,
530 "RI_MOD: Cr=%06o CA(Before)=%06o\n", Cr, cpu.TPR.CA);
531
532 if (cpu.cu.rpt || cpu.cu.rd || cpu.cu.rl)
533 {
534 if (cpu.currentInstruction.b29)
535 {
536 word3 PRn = GET_PRN(IWB_IRODD);
537 #ifdef TESTING
538 HDBGRegPRR (PRn, "rpx b29");
539 #endif
540 CPTUR (cptUsePRn + PRn);
541 cpu.TPR.CA = Cr + cpu.PR [PRn].WORDNO;
542 }
543 else
544 {
545 cpu.TPR.CA = Cr;
546 }
547 cpu.TPR.CA &= AMASK;
548 }
549 else
550 {
551 cpu.TPR.CA += Cr;
552 cpu.TPR.CA &= MASK18;
553 }
554 sim_debug (DBG_ADDRMOD, & cpu_dev,
555 "RI_MOD: CA(After)=%06o\n", cpu.TPR.CA);
556 }
557
558
559
560
561 if (GET_TM(cpu.cu.CT_HOLD) == TM_IR)
562 {
563 goto IR_MOD_2;
564 }
565
566
567
568
569 word18 saveCA = cpu.TPR.CA;
570 ReadIndirect ();
571
572 if ((saveCA & 1) == 0 && (ISITP (cpu.itxPair[0]) || ISITS (cpu.itxPair[0])))
573 {
574 do_ITS_ITP ();
575 updateIWB (cpu.TPR.CA, cpu.rTAG);
576 }
577 else
578 {
579 cpu.rTAG = GET_TAG (cpu.itxPair[0]);
580 if (ISITP (cpu.itxPair[0]) || ISITS (cpu.itxPair[0]))
581 {
582 sim_warn ("%s: itp/its at odd address\n", __func__);
583 #ifdef TESTING
584 traceInstruction (0);
585 #endif
586 }
587 if (!(cpu.cu.rpt || cpu.cu.rd || cpu.cu.rl))
588 {
589 updateIWB (GET_ADDR (cpu.itxPair[0]), cpu.rTAG);
590 }
591
592 if (GET_TM (cpu.rTAG) == TM_IT)
593 {
594 if (GET_TD (cpu.rTAG) == IT_F2)
595 {
596 doFault (FAULT_F2, fst_zero, "RI_MOD: IT_F2 (0)");
597 }
598 if (GET_TD (cpu.rTAG) == IT_F3)
599 {
600 doFault (FAULT_F3, fst_zero, "RI_MOD: IT_F3");
601 }
602 }
603 cpu.TPR.CA = GETHI (cpu.itxPair[0]);
604 cpu.rY = cpu.TPR.CA;
605 }
606
607
608
609
610
611
612
613 sim_debug (DBG_ADDRMOD, & cpu_dev,
614 "RI_MOD: cpu.itxPair[0]=%012"PRIo64
615 " TPR.CA=%06o rTAG=%02o\n",
616 cpu.itxPair[0], cpu.TPR.CA, cpu.rTAG);
617
618
619
620 if (cpu.cu.rpt || cpu.cu.rd || cpu.cu.rl)
621 return;
622
623 goto startCA;
624 }
625
626
627 IR_MOD:;
628 {
629 IR_MOD_1:;
630
631 sim_debug (DBG_ADDRMOD, & cpu_dev,
632 "IR_MOD: CT_HOLD=%o %o\n", cpu.cu.CT_HOLD, Td);
633
634 IR_MOD_2:;
635
636 if (++ lockupCnt > lockupLimit)
637 {
638 doFault (FAULT_LUF, fst_zero, "Lockup in addrmod IR mode");
639 }
640
641 sim_debug (DBG_ADDRMOD, & cpu_dev,
642 "IR_MOD: fetching indirect word from %06o\n",
643 cpu.TPR.CA);
644
645 word18 saveCA = cpu.TPR.CA;
646 ReadIndirect ();
647
648
649 if (GET_TM(cpu.rTAG) == TM_IR)
650 cpu.cu.CT_HOLD = cpu.rTAG;
651
652 if ((saveCA & 1) == 0 && (ISITP (cpu.itxPair[0]) || ISITS (cpu.itxPair[0])))
653 {
654 do_ITS_ITP ();
655 }
656 else
657 {
658 if (ISITP (cpu.itxPair[0]) || ISITS (cpu.itxPair[0]))
659 {
660 sim_warn ("%s: itp/its at odd address\n", __func__);
661 #ifdef TESTING
662 traceInstruction (0);
663 #endif
664 }
665 cpu.TPR.CA = GETHI (cpu.itxPair[0]);
666 cpu.rY = cpu.TPR.CA;
667 cpu.rTAG = GET_TAG (cpu.itxPair[0]);
668 }
669
670 sim_debug (DBG_ADDRMOD, & cpu_dev,
671 "IR_MOD: CT_HOLD=%o\n", cpu.cu.CT_HOLD);
672 Td = GET_TD (cpu.rTAG);
673 Tm = GET_TM (cpu.rTAG);
674
675 sim_debug (DBG_ADDRMOD, & cpu_dev,
676 "IR_MOD1: cpu.itxPair[0]=%012"PRIo64
677 " TPR.CA=%06o Tm=%o Td=%02o (%s)\n",
678 cpu.itxPair[0], cpu.TPR.CA, Tm, Td,
679 get_mod_string (buf, GET_TAG (cpu.itxPair[0])));
680
681 switch (Tm)
682 {
683 case TM_IT:
684 {
685 sim_debug (DBG_ADDRMOD, & cpu_dev,
686 "IR_MOD(TM_IT): Td=%02o => %02o\n",
687 Td, cpu.cu.CT_HOLD);
688
689 if (Td == IT_F2 || Td == IT_F3)
690 {
691 updateIWB(cpu.TPR.CA, cpu.rTAG);
692
693 switch (Td)
694 {
695 case IT_F2:
696 cpu.TPR.CA = saveCA;
697 doFault (FAULT_F2, fst_zero, "TM_IT: IT_F2 (1)");
698
699
700 case IT_F3:
701 cpu.TPR.CA = saveCA;
702 doFault (FAULT_F3, fst_zero, "TM_IT: IT_F3");
703 }
704 }
705
706 #ifndef __SUNPRO_C
707 # ifndef __SUNPRO_CC
708 # ifndef __SUNPRO_CC_COMPAT
709
710
711 # if defined(__GNUC__) && __GNUC__ > 6
712 __attribute__ ((fallthrough));
713 # endif
714
715 # ifdef __clang__
716 (void)0;
717 # endif
718 # endif
719 # endif
720 #endif
721 }
722
723
724 case TM_R:
725 {
726 word6 Td_hold = GET_TD (cpu.cu.CT_HOLD);
727 cpu.rTAG = (TM_R | Td_hold);
728 updateIWB (cpu.TPR.CA, cpu.rTAG);
729 goto startCA;
730 }
731
732 case TM_RI:
733 {
734 if (Td == TD_DU || Td == TD_DL)
735 doFault (FAULT_IPR, fst_ill_mod,
736 "RI_MOD: Td == TD_DU || Td == TD_DL");
737
738 word18 Cr = get_Cr (Td);
739
740 sim_debug (DBG_ADDRMOD, & cpu_dev,
741 "IR_MOD(TM_RI): Td=%o Cr=%06o TPR.CA(Before)=%06o\n",
742 Td, Cr, cpu.TPR.CA);
743
744 cpu.TPR.CA += Cr;
745 cpu.TPR.CA &= MASK18;
746
747 sim_debug (DBG_ADDRMOD, & cpu_dev,
748 "IR_MOD(TM_RI): TPR.CA=%06o\n", cpu.TPR.CA);
749
750 sim_debug (DBG_ADDRMOD, & cpu_dev,
751 "IR_MOD(TM_RI): TPR.CA(After)=%06o\n",
752 cpu.TPR.CA);
753
754
755 updateIWB (cpu.TPR.CA, (TM_RI|TD_N));
756 goto IR_MOD_2;
757 }
758
759 case TM_IR:
760 {
761 updateIWB (cpu.TPR.CA, cpu.rTAG);
762 goto IR_MOD_1;
763 }
764 }
765
766 sim_printf ("%s(IR_MOD): unknown Tm??? %o\n",
767 __func__, GET_TM (cpu.rTAG));
768 return;
769 }
770
771 IT_MOD:;
772 {
773
774
775
776
777
778
779
780
781
782
783 word6 idwtag, delta;
784 word24 Yi = (word24) -1;
785
786 switch (Td)
787 {
788
789 case SPEC_ITP:
790
791 case SPEC_ITS:
792 {
793 doFault(FAULT_IPR, fst_ill_mod, "ITx in IT_MOD)");
794 }
795
796
797 case 2:
798 {
799 sim_debug (DBG_ADDRMOD, & cpu_dev,
800 "IT_MOD(): illegal procedure, illegal modifier, "
801 "fault Td=%o\n", Td);
802 doFault (FAULT_IPR, fst_ill_mod,
803 "IT_MOD(): illegal procedure, illegal modifier, "
804 "fault");
805 }
806
807
808 case IT_F1:
809 {
810 doFault(FAULT_F1, fst_zero, "IT_MOD: IT_F1");
811 }
812
813
814 case IT_F2:
815 {
816 doFault(FAULT_F2, fst_zero, "IT_MOD: IT_F2 (2)");
817 }
818
819
820 case IT_F3:
821 {
822 doFault(FAULT_F3, fst_zero, "IT_MOD: IT_F3");
823 }
824
825
826 case IT_CI:
827
828 case IT_SC:
829
830 case IT_SCR:
831 {
832
833
834
835
836
837
838 sim_debug (DBG_ADDRMOD, & cpu_dev,
839 "IT_MOD CI/SC/SCR reading indirect word from %06o\n",
840 cpu.TPR.CA);
841
842
843
844
845
846 word36 indword;
847 word18 indaddr = cpu.TPR.CA;
848 ReadAPUDataRead (indaddr, & indword);
849 #ifdef LOCKLESS
850 word24 phys_address = cpu.iefpFinalAddress;
851 #endif
852
853 sim_debug (DBG_ADDRMOD, & cpu_dev,
854 "IT_MOD CI/SC/SCR indword=%012"PRIo64"\n", indword);
855
856
857
858
859
860 Yi = GET_ADDR (indword);
861 word6 sz = GET_TB (GET_TAG (indword));
862 word3 os = GET_CF (GET_TAG (indword));
863 word12 tally = GET_TALLY (indword);
864
865 sim_debug (DBG_ADDRMOD, & cpu_dev,
866 "IT_MOD CI/SC/SCR size=%o offset=%o Yi=%06o\n",
867 sz, os, Yi);
868
869 if (sz == TB6 && os > 5)
870
871 doFault (FAULT_IPR, fst_ill_mod,
872 "co size == TB6 && offset > 5");
873
874 if (sz == TB9 && os > 3)
875
876 doFault (FAULT_IPR, fst_ill_mod,
877 "co size == TB9 && offset > 3");
878
879
880
881 cpu.TPR.CA = Yi;
882 cpu.ou.character_address = Yi;
883 cpu.ou.characterOperandSize = sz;
884 cpu.ou.characterOperandOffset = os;
885
886
887
888 if (Td == IT_SCR)
889 {
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909 if (os == 0)
910 {
911 if (sz == TB6)
912 os = 5;
913 else
914 os = 3;
915 Yi -= 1;
916 Yi &= MASK18;
917 }
918 else
919 {
920 os -= 1;
921 }
922
923 CPT (cpt2L, 5);
924 tally ++;
925 tally &= 07777;
926
927
928
929 cpu.TPR.CA = Yi;
930 cpu.ou.character_address = Yi;
931 cpu.ou.characterOperandSize = sz;
932 cpu.ou.characterOperandOffset = os;
933 }
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948 cpu.cu.pot = 1;
949
950 #ifdef LOCKLESSXXX
951
952 Read (cpu.TPR.CA, & cpu.ou.character_data, (i->info->flags & RMW) == \
953 STORE_OPERAND ? OPERAND_RMW : OPERAND_READ);
954 #else
955 ReadOperandRead (cpu.TPR.CA, & cpu.ou.character_data);
956 #endif
957 #ifdef LOCKLESS
958 cpu.char_word_address = cpu.iefpFinalAddress;
959 #endif
960
961 sim_debug (DBG_ADDRMOD, & cpu_dev,
962 "IT_MOD CI/SC/SCR data=%012"PRIo64"\n",
963 cpu.ou.character_data);
964
965 cpu.cu.pot = 0;
966
967 if (Td == IT_SC)
968 {
969
970
971
972
973
974
975
976
977
978
979
980
981 os ++;
982
983 if (((sz == TB6) && (os > 5)) ||
984 ((sz == TB9) && (os > 3)))
985 {
986 os = 0;
987 Yi += 1;
988 Yi &= MASK18;
989 }
990 CPT (cpt2L, 6);
991 tally --;
992 tally &= 07777;
993 }
994
995 if (Td == IT_SC || Td == IT_SCR)
996 {
997 sim_debug (DBG_ADDRMOD, & cpu_dev,
998 "update IT tally now %o\n", tally);
999
1000
1001
1002
1003
1004
1005 #ifdef LOCKLESS
1006 word36 indword_new;
1007 core_read_lock(phys_address, &indword_new, __func__);
1008 if (indword_new != indword)
1009 sim_warn("indword changed from %llo to %llo\n",
1010 (long long unsigned int)indword,
1011 (long long unsigned int)indword_new);
1012 #endif
1013 putbits36_18 (& indword, 0, Yi);
1014 putbits36_12 (& indword, 18, tally);
1015 putbits36_3 (& indword, 33, os);
1016 #ifdef LOCKLESS
1017 core_write_unlock(phys_address, indword, __func__);
1018 #else
1019 WriteAPUDataStore (indaddr, indword);
1020 #endif
1021
1022 SC_I_TALLY (tally == 0);
1023
1024 sim_debug (DBG_ADDRMOD, & cpu_dev,
1025 "update IT wrote tally word %012"PRIo64
1026 " to %06o\n",
1027 indword, cpu.TPR.CA);
1028 }
1029
1030
1031
1032 cpu.TPR.CA = cpu.ou.character_address;
1033 return;
1034 }
1035
1036 case IT_I:
1037 {
1038 sim_debug (DBG_ADDRMOD, & cpu_dev,
1039 "IT_MOD(IT_I): reading indirect word from %06o\n",
1040 cpu.TPR.CA);
1041
1042
1043 ReadIndirect ();
1044
1045 sim_debug (DBG_ADDRMOD, & cpu_dev,
1046 "IT_MOD(IT_I): indword=%012"PRIo64"\n",
1047 cpu.itxPair[0]);
1048
1049 cpu.TPR.CA = GET_ADDR (cpu.itxPair[0]);
1050 updateIWB (cpu.TPR.CA, (TM_R|TD_N));
1051 return;
1052 }
1053
1054 case IT_AD:
1055 {
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066 sim_debug (DBG_ADDRMOD, & cpu_dev,
1067 "IT_MOD(IT_AD): reading indirect word from %06o\n",
1068 cpu.TPR.CA);
1069
1070 #ifdef THREADZ
1071 lock_rmw ();
1072 #endif
1073
1074 word18 saveCA = cpu.TPR.CA;
1075 word36 indword;
1076 ReadAPUDataRMW (cpu.TPR.CA, & indword);
1077
1078 cpu.AM_tally = GET_TALLY (indword);
1079 delta = GET_DELTA (indword);
1080 Yi = GETHI (indword);
1081
1082 sim_debug (DBG_ADDRMOD, & cpu_dev,
1083 "IT_MOD(IT_AD): indword=%012"PRIo64"\n",
1084 indword);
1085 sim_debug (DBG_ADDRMOD, & cpu_dev,
1086 "IT_MOD(IT_AD): address:%06o tally:%04o "
1087 "delta:%03o\n",
1088 Yi, cpu.AM_tally, delta);
1089
1090 cpu.TPR.CA = Yi;
1091 word18 computedAddress = cpu.TPR.CA;
1092
1093 Yi += delta;
1094 Yi &= MASK18;
1095
1096 cpu.AM_tally -= 1;
1097 cpu.AM_tally &= 07777;
1098
1099
1100
1101 SC_I_TALLY (cpu.AM_tally == 0);
1102 indword = (word36) (((word36) Yi << 18) |
1103 (((word36) cpu.AM_tally & 07777) << 6) |
1104 delta);
1105 #ifdef LOCKLESS
1106 core_write_unlock(cpu.iefpFinalAddress, indword, __func__);
1107 #else
1108 WriteAPUDataStore (saveCA, indword);
1109 #endif
1110
1111 #ifdef THREADZ
1112 unlock_rmw ();
1113 #endif
1114
1115 sim_debug (DBG_ADDRMOD, & cpu_dev,
1116 "IT_MOD(IT_AD): wrote tally word %012"PRIo64
1117 " to %06o\n",
1118 indword, saveCA);
1119
1120 cpu.TPR.CA = computedAddress;
1121 updateIWB (cpu.TPR.CA, (TM_R|TD_N));
1122 return;
1123 }
1124
1125 case IT_SD:
1126 {
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137 #ifdef THREADZ
1138 lock_rmw ();
1139 #endif
1140
1141 word18 saveCA = cpu.TPR.CA;
1142 word36 indword;
1143 ReadAPUDataRMW (cpu.TPR.CA, & indword);
1144
1145 sim_debug (DBG_ADDRMOD, & cpu_dev,
1146 "IT_MOD(IT_SD): reading indirect word from %06o\n",
1147 cpu.TPR.CA);
1148 cpu.AM_tally = GET_TALLY (indword);
1149 delta = GET_DELTA (indword);
1150 Yi = GETHI (indword);
1151
1152 sim_debug (DBG_ADDRMOD, & cpu_dev,
1153 "IT_MOD(IT_SD): indword=%012"PRIo64"\n",
1154 indword);
1155 sim_debug (DBG_ADDRMOD, & cpu_dev,
1156 "IT_MOD(IT_SD): address:%06o tally:%04o "
1157 "delta:%03o\n",
1158 Yi, cpu.AM_tally, delta);
1159
1160 Yi -= delta;
1161 Yi &= MASK18;
1162 cpu.TPR.CA = Yi;
1163
1164 cpu.AM_tally += 1;
1165 cpu.AM_tally &= 07777;
1166 if (cpu.AM_tally == 0)
1167 SET_I_TALLY;
1168
1169
1170 indword = (word36) (((word36) Yi << 18) |
1171 (((word36) cpu.AM_tally & 07777) << 6) |
1172 delta);
1173 #ifdef LOCKLESS
1174 core_write_unlock(cpu.iefpFinalAddress, indword, __func__);
1175 #else
1176 WriteAPUDataStore (saveCA, indword);
1177 #endif
1178
1179 #ifdef THREADZ
1180 unlock_rmw ();
1181 #endif
1182
1183 sim_debug (DBG_ADDRMOD, & cpu_dev,
1184 "IT_MOD(IT_SD): wrote tally word %012"PRIo64
1185 " to %06o\n",
1186 indword, saveCA);
1187
1188 cpu.TPR.CA = Yi;
1189 updateIWB (cpu.TPR.CA, (TM_R|TD_N));
1190 return;
1191 }
1192
1193 case IT_DI:
1194 {
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204 sim_debug (DBG_ADDRMOD, & cpu_dev,
1205 "IT_MOD(IT_DI): reading indirect word from %06o\n",
1206 cpu.TPR.CA);
1207
1208 #ifdef THREADZ
1209 lock_rmw ();
1210 #endif
1211
1212 word18 saveCA = cpu.TPR.CA;
1213 word36 indword;
1214 ReadAPUDataRMW (cpu.TPR.CA, & indword);
1215
1216 Yi = GETHI (indword);
1217 cpu.AM_tally = GET_TALLY (indword);
1218 word6 junk = GET_TAG (indword);
1219
1220 sim_debug (DBG_ADDRMOD, & cpu_dev,
1221 "IT_MOD(IT_DI): indword=%012"PRIo64"\n",
1222 indword);
1223 sim_debug (DBG_ADDRMOD, & cpu_dev,
1224 "IT_MOD(IT_DI): address:%06o tally:%04o\n",
1225 Yi, cpu.AM_tally);
1226
1227 Yi -= 1;
1228 Yi &= MASK18;
1229 cpu.TPR.CA = Yi;
1230
1231 cpu.AM_tally += 1;
1232 cpu.AM_tally &= 07777;
1233 SC_I_TALLY (cpu.AM_tally == 0);
1234
1235
1236
1237 indword = (word36) (((word36) cpu.TPR.CA << 18) |
1238 ((word36) cpu.AM_tally << 6) |
1239 junk);
1240
1241 sim_debug (DBG_ADDRMOD, & cpu_dev,
1242 "IT_MOD(IT_DI): writing indword=%012"PRIo64" to "
1243 "addr %06o\n",
1244 indword, saveCA);
1245
1246 #ifdef LOCKLESS
1247 core_write_unlock(cpu.iefpFinalAddress, indword, __func__);
1248 #else
1249 WriteAPUDataStore (saveCA, indword);
1250 #endif
1251
1252 #ifdef THREADZ
1253 unlock_rmw ();
1254 #endif
1255 cpu.TPR.CA = Yi;
1256 updateIWB (cpu.TPR.CA, (TM_R|TD_N));
1257 return;
1258 }
1259
1260 case IT_ID:
1261 {
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271 word18 saveCA = cpu.TPR.CA;
1272
1273 sim_debug (DBG_ADDRMOD, & cpu_dev,
1274 "IT_MOD(IT_ID): fetching indirect word from %06o\n",
1275 cpu.TPR.CA);
1276
1277 #ifdef THREADZ
1278 lock_rmw ();
1279 #endif
1280
1281 word36 indword;
1282 ReadAPUDataRMW (cpu.TPR.CA, & indword);
1283
1284 Yi = GETHI (indword);
1285 cpu.AM_tally = GET_TALLY (indword);
1286
1287 word6 junk = GET_TAG (indword);
1288 sim_debug (DBG_ADDRMOD, & cpu_dev,
1289 "IT_MOD(IT_ID): indword=%012"PRIo64
1290 " Yi=%06o tally=%04o\n",
1291 indword, Yi, cpu.AM_tally);
1292
1293 cpu.TPR.CA = Yi;
1294 word18 computedAddress = cpu.TPR.CA;
1295
1296 Yi += 1;
1297 Yi &= MASK18;
1298
1299 cpu.AM_tally -= 1;
1300 cpu.AM_tally &= 07777;
1301
1302
1303
1304
1305 SC_I_TALLY (cpu.AM_tally == 0);
1306
1307
1308 indword = (word36) (((word36) Yi << 18) |
1309 ((word36) cpu.AM_tally << 6) |
1310 junk);
1311
1312 sim_debug (DBG_ADDRMOD, & cpu_dev,
1313 "IT_MOD(IT_ID): writing indword=%012"PRIo64" to "
1314 "addr %06o\n",
1315 indword, saveCA);
1316
1317 #ifdef LOCKLESS
1318 core_write_unlock(cpu.iefpFinalAddress, indword, __func__);
1319 #else
1320 WriteAPUDataStore (saveCA, indword);
1321 #endif
1322
1323 #ifdef THREADZ
1324 unlock_rmw ();
1325 #endif
1326
1327 cpu.TPR.CA = computedAddress;
1328 updateIWB (cpu.TPR.CA, (TM_R|TD_N));
1329 return;
1330 }
1331
1332
1333 case IT_DIC:
1334 {
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355 sim_debug (DBG_ADDRMOD, & cpu_dev,
1356 "IT_MOD(IT_DIC): fetching indirect word from %06o\n",
1357 cpu.TPR.CA);
1358
1359 #ifdef THREADZ
1360 lock_rmw ();
1361 #endif
1362
1363 word18 saveCA = cpu.TPR.CA;
1364 word36 indword;
1365 ReadAPUDataRMW (cpu.TPR.CA, & indword);
1366
1367 cpu.cu.pot = 0;
1368
1369 Yi = GETHI (indword);
1370 cpu.AM_tally = GET_TALLY (indword);
1371 idwtag = GET_TAG (indword);
1372
1373 sim_debug (DBG_ADDRMOD, & cpu_dev,
1374 "IT_MOD(IT_DIC): indword=%012"PRIo64" Yi=%06o "
1375 "tally=%04o idwtag=%02o\n",
1376 indword, Yi, cpu.AM_tally, idwtag);
1377
1378 word24 YiSafe2 = Yi;
1379
1380 Yi -= 1;
1381 Yi &= MASK18;
1382
1383 cpu.AM_tally += 1;
1384 cpu.AM_tally &= 07777;
1385
1386
1387
1388
1389
1390
1391
1392 indword = (word36) (((word36) Yi << 18) |
1393 ((word36) cpu.AM_tally << 6) | idwtag);
1394
1395 sim_debug (DBG_ADDRMOD, & cpu_dev,
1396 "IT_MOD(IT_DIC): writing indword=%012"PRIo64" to "
1397 "addr %06o\n", indword, saveCA);
1398
1399 #ifdef LOCKLESS
1400 core_write_unlock(cpu.iefpFinalAddress, indword, __func__);
1401 #else
1402 WriteAPUDataStore (saveCA, indword);
1403 #endif
1404
1405 #ifdef THREADZ
1406 unlock_rmw ();
1407 #endif
1408
1409
1410
1411
1412
1413
1414
1415
1416 cpu.TPR.CA = Yi;
1417
1418 sim_debug (DBG_ADDRMOD, & cpu_dev,
1419 "IT_MOD(IT_DIC): new CT_HOLD %02o new TAG %02o\n",
1420 cpu.rTAG, idwtag);
1421 cpu.cu.CT_HOLD = cpu.rTAG;
1422 cpu.rTAG = idwtag;
1423
1424 Tm = GET_TM (cpu.rTAG);
1425 if (Tm == TM_RI || Tm == TM_R)
1426 {
1427 if (GET_TD (cpu.rTAG) != 0)
1428 {
1429 doFault (FAULT_IPR, fst_ill_mod,
1430 "DIC Incorrect address modifier");
1431 }
1432 }
1433
1434
1435
1436 SC_I_TALLY (cpu.AM_tally == 0);
1437 if (cpu.tweaks.isolts_mode)
1438 updateIWB (YiSafe2, cpu.rTAG);
1439 else
1440 updateIWB (cpu.TPR.CA, cpu.rTAG);
1441 goto startCA;
1442 }
1443
1444
1445 case IT_IDC:
1446 {
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467 sim_debug (DBG_ADDRMOD, & cpu_dev,
1468 "IT_MOD(IT_IDC): fetching indirect word from %06o\n",
1469 cpu.TPR.CA);
1470
1471 #ifdef THREADZ
1472 lock_rmw ();
1473 #endif
1474
1475 word18 saveCA = cpu.TPR.CA;
1476 word36 indword;
1477 ReadAPUDataRMW (cpu.TPR.CA, & indword);
1478
1479 cpu.cu.pot = 0;
1480
1481 Yi = GETHI (indword);
1482 cpu.AM_tally = GET_TALLY (indword);
1483 idwtag = GET_TAG (indword);
1484
1485 sim_debug (DBG_ADDRMOD, & cpu_dev,
1486 "IT_MOD(IT_IDC): indword=%012"PRIo64" Yi=%06o "
1487 "tally=%04o idwtag=%02o\n",
1488 indword, Yi, cpu.AM_tally, idwtag);
1489
1490 word24 YiSafe = Yi;
1491
1492 Yi += 1;
1493 Yi &= MASK18;
1494
1495 cpu.AM_tally -= 1;
1496 cpu.AM_tally &= 07777;
1497
1498
1499
1500
1501
1502 indword = (word36) (((word36) Yi << 18) |
1503 ((word36) cpu.AM_tally << 6) |
1504 idwtag);
1505
1506 sim_debug (DBG_ADDRMOD, & cpu_dev,
1507 "IT_MOD(IT_IDC): writing indword=%012"PRIo64""
1508 " to addr %06o\n",
1509 indword, saveCA);
1510
1511 #ifdef LOCKLESS
1512 core_write_unlock(cpu.iefpFinalAddress, indword, __func__);
1513 #else
1514 WriteAPUDataStore (saveCA, indword);
1515 #endif
1516
1517 #ifdef THREADZ
1518 unlock_rmw ();
1519 #endif
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530 cpu.TPR.CA = YiSafe;
1531
1532 sim_debug (DBG_ADDRMOD, & cpu_dev,
1533 "IT_MOD(IT_IDC): new CT_HOLD %02o new TAG %02o\n",
1534 cpu.rTAG, idwtag);
1535 cpu.cu.CT_HOLD = cpu.rTAG;
1536 cpu.rTAG = idwtag;
1537
1538 Tm = GET_TM (cpu.rTAG);
1539 if (Tm == TM_RI || Tm == TM_R)
1540 {
1541 if (GET_TD (cpu.rTAG) != 0)
1542 {
1543 doFault (FAULT_IPR, fst_ill_mod,
1544 "IDC Incorrect address modifier");
1545 }
1546 }
1547
1548
1549
1550 SC_I_TALLY (cpu.AM_tally == 0);
1551 updateIWB (cpu.TPR.CA, cpu.rTAG);
1552
1553 goto startCA;
1554 }
1555 }
1556 sim_printf ("IT_MOD/Td how did we get here?\n");
1557 return;
1558 }
1559 }