This source file includes following definitions.
- get4
- get6
- get9
- put4
- put6
- put9
- getCrAR
- getMFReg18
- getMFReg36
- EISWriteCache
- EISReadCache
- EISWriteIdx
- EISReadIdx
- EISRead
- EISReadPage
- EISWritePage
- EISget469
- EISput469
- EISget49
- EISgetBitRWN
- setupOperandDescriptorCache
- setupOperandDescriptor
- setupEISoperands
- parseAlphanumericOperandDescriptor
- parseArgOperandDescriptor
- parseNumericOperandDescriptor
- parseBitstringOperandDescriptor
- cleanupOperandDescriptor
- tandd_eis_interruptible
- tandd_eis_sample
- a4bd
- s4bd
- axbd
- abd
- awd
- sbd
- swd
- s9bd
- asxbd
- cmpc
- scd
- scdr
- scm
- scmr
- xlate
- tct
- tctr
- isGBCDOvp
- mlr
- mrl
- EISloadInputBufferNumeric
- EISloadInputBufferAlphnumeric
- EISwriteOutputBufferToMemory
- writeToOutputBuffer
- mopCHT
- mopENF
- mopIGN
- mopINSA
- mopINSB
- mopINSM
- mopINSN
- mopINSP
- mopLTE
- mopMFLC
- mopMFLS
- mopMORS
- mopMVC
- mopMSES
- mopMVZA
- mopMVZB
- mopSES
- EISgetMop
- mopExecutor
- mve
- mvne
- mvt
- cmpn
- EISwrite4
- EISwrite9
- EISwrite49
- mvn
- csl
- getBitOffsets
- EISgetBitRWNR
- csr
- sztl
- sztr
- EISgetBit
- cmpb
- sign9n
- signExt9
- load9x
- btd
- dtb
- ad2d
- ad3d
- sb2d
- sb3d
- mp2d
- mp3d
- dv2d
- dv3d
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 #if defined(EIS_PTR)
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51 #endif
52
53 #include <ctype.h>
54
55 #include "dps8.h"
56 #include "dps8_sys.h"
57 #include "dps8_iom.h"
58 #include "dps8_cable.h"
59 #include "dps8_cpu.h"
60 #include "dps8_faults.h"
61 #include "dps8_scu.h"
62 #include "dps8_iefp.h"
63 #include "dps8_decimal.h"
64 #include "dps8_ins.h"
65 #include "dps8_eis.h"
66 #include "dps8_utils.h"
67
68 #define DBG_CTR cpu.cycleCnt
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111 #define ABD_BITS
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130 static word4 get4 (word36 w, int pos)
131 {
132 switch (pos)
133 {
134 case 0:
135 return getbits36_4 (w, 1);
136
137 case 1:
138 return getbits36_4 (w, 5);
139
140 case 2:
141 return getbits36_4 (w, 10);
142
143 case 3:
144 return getbits36_4 (w, 14);
145
146 case 4:
147 return getbits36_4 (w, 19);
148
149 case 5:
150 return getbits36_4 (w, 23);
151
152 case 6:
153 return getbits36_4 (w, 28);
154
155 case 7:
156 return getbits36_4 (w, 32);
157
158 }
159 sim_printf ("get4(): How'd we get here?\r\n");
160 return 0;
161 }
162
163
164 static word4 get6 (word36 w, int pos)
165 {
166 switch (pos)
167 {
168 case 0:
169 return getbits36_6 (w, 0);
170
171 case 1:
172 return getbits36_6 (w, 6);
173
174 case 2:
175 return getbits36_6 (w, 12);
176
177 case 3:
178 return getbits36_6 (w, 18);
179
180 case 4:
181 return getbits36_6 (w, 24);
182
183 case 5:
184 return getbits36_6 (w, 30);
185
186 }
187 sim_printf ("get6(): How'd we get here?\r\n");
188 return 0;
189 }
190
191
192 static word9 get9(word36 w, int pos)
193 {
194 switch (pos)
195 {
196 case 0:
197 return getbits36_9 (w, 0);
198
199 case 1:
200 return getbits36_9 (w, 9);
201
202 case 2:
203 return getbits36_9 (w, 18);
204
205 case 3:
206 return getbits36_9 (w, 27);
207
208 }
209 sim_printf ("get9(): How'd we get here?\r\n");
210 return 0;
211 }
212
213
214 static word36 put4 (word36 w, int pos, word4 c)
215 {
216
217
218
219
220
221 c &= MASK4;
222 switch (pos)
223 {
224 case 0:
225
226 return setbits36_5 (w, 0, c);
227
228 case 1:
229 return setbits36_4 (w, 5, c);
230
231 case 2:
232
233 return setbits36_5 (w, 9, c);
234
235 case 3:
236 return setbits36_4 (w, 14, c);
237
238 case 4:
239
240 return setbits36_5 (w, 18, c);
241
242 case 5:
243 return setbits36_4 (w, 23, c);
244
245 case 6:
246
247 return setbits36_5 (w, 27, c);
248
249 case 7:
250 return setbits36_4 (w, 32, c);
251 }
252 sim_printf ("put4(): How'd we get here?\r\n");
253 return 0;
254 }
255
256
257 static word36 put6 (word36 w, int pos, word6 c)
258 {
259 switch (pos)
260 {
261 case 0:
262
263 return setbits36_6 (w, 0, c);
264
265 case 1:
266
267 return setbits36_6 (w, 6, c);
268
269 case 2:
270
271 return setbits36_6 (w, 12, c);
272
273 case 3:
274
275 return setbits36_6 (w, 18, c);
276
277 case 4:
278
279 return setbits36_6 (w, 24, c);
280
281 case 5:
282
283 return setbits36_6 (w, 30, c);
284
285 }
286 sim_printf ("put6(): How'd we get here?\r\n");
287 return 0;
288 }
289
290
291 static word36 put9 (word36 w, int pos, word9 c)
292 {
293 switch (pos)
294 {
295 case 0:
296
297 return setbits36_9 (w, 0, c);
298
299 case 1:
300
301 return setbits36_9 (w, 9, c);
302
303 case 2:
304
305 return setbits36_9 (w, 18, c);
306
307 case 3:
308
309 return setbits36_9 (w, 27, c);
310
311 }
312 sim_printf ("put9(): How'd we get here?\r\n");
313 return 0;
314 }
315
316
317
318
319
320
321 static word36 getCrAR (cpu_state_t * cpup, word4 reg)
322 {
323 if (reg == 0)
324 return 0;
325
326 if (reg & 010)
327 return cpu.rX [X (reg)];
328
329 switch (reg)
330 {
331 case TD_N:
332 return 0;
333
334 case TD_AU:
335 #if defined(TESTING)
336 HDBGRegAR ("au");
337 #endif
338 return GETHI (cpu.rA);
339
340 case TD_QU:
341 #if defined(TESTING)
342 HDBGRegAR ("qu");
343 #endif
344 return GETHI (cpu.rQ);
345
346 case TD_IC:
347 return cpu.PPR.IC;
348
349 case TD_AL:
350 #if defined(TESTING)
351 HDBGRegAR ("al");
352 #endif
353 return cpu.rA;
354
355 case TD_QL:
356 #if defined(TESTING)
357 HDBGRegAR ("ql");
358 #endif
359 return cpu.rQ;
360 }
361 return 0;
362 }
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384 static word18 getMFReg18 (cpu_state_t * cpup, uint n, bool allowDU, bool allowNIC, fault_ipr_subtype_ *mod_fault)
385 {
386 switch (n)
387 {
388 case 0:
389 if (! allowNIC)
390 {
391
392 *mod_fault |= FR_ILL_MOD;
393
394 }
395 return 0;
396
397 case 1:
398 #if defined(TESTING)
399 HDBGRegAR ("au");
400 #endif
401 return GETHI (cpu.rA);
402
403 case 2:
404 #if defined(TESTING)
405 HDBGRegAR ("qu");
406 #endif
407 return GETHI (cpu.rQ);
408
409 case 3:
410
411
412
413 if (! allowDU)
414 {
415
416
417
418
419
420
421
422
423
424
425
426
427
428 *mod_fault |= FR_ILL_MOD;
429
430 }
431 return 0;
432
433 case 4:
434
435
436
437
438 if (! allowNIC)
439 {
440
441 *mod_fault |= FR_ILL_MOD;
442
443 }
444 return cpu.PPR.IC;
445
446 case 5:
447 #if defined(TESTING)
448 HDBGRegAR ("al/a");
449 #endif
450 return GETLO (cpu.rA);
451
452 case 6:
453 #if defined(TESTING)
454 HDBGRegAR ("ql/a");
455 #endif
456 return GETLO (cpu.rQ);
457
458 case 7:
459 *mod_fault |= FR_ILL_MOD;
460
461 return 0;
462
463 case 8:
464 case 9:
465 case 10:
466 case 11:
467 case 12:
468 case 13:
469 case 14:
470 case 15:
471 return cpu.rX [n - 8];
472 }
473 sim_printf ("getMFReg18(cpup, ): How'd we get here? n=%d\r\n", n);
474 return 0;
475 }
476
477 static word36 getMFReg36 (cpu_state_t * cpup, uint n, bool allowDU, bool allowNIC, fault_ipr_subtype_ *mod_fault)
478 {
479 switch (n)
480 {
481 case 0:
482 if (! allowNIC)
483 {
484
485 *mod_fault |= FR_ILL_MOD;
486
487 }
488 return 0;
489 case 1:
490 #if defined(TESTING)
491 HDBGRegAR ("au");
492 #endif
493 return GETHI (cpu.rA);
494
495 case 2:
496 #if defined(TESTING)
497 HDBGRegAR ("qu");
498 #endif
499 return GETHI (cpu.rQ);
500
501 case 3:
502
503 if (! allowDU)
504 *mod_fault |= FR_ILL_MOD;
505
506 return 0;
507
508 case 4:
509
510
511
512
513 if (! allowNIC)
514 {
515
516 *mod_fault |= FR_ILL_MOD;
517
518 }
519 return cpu.PPR.IC;
520
521 case 5:
522 #if defined(TESTING)
523 HDBGRegAR ("al/a");
524 #endif
525 return cpu.rA;
526
527 case 6:
528 #if defined(TESTING)
529 HDBGRegAR ("ql/a");
530 #endif
531 return cpu.rQ;
532
533 case 7:
534 *mod_fault |= FR_ILL_MOD;
535
536 return 0;
537
538 case 8:
539 case 9:
540 case 10:
541 case 11:
542 case 12:
543 case 13:
544 case 14:
545 case 15:
546 return cpu.rX [n - 8];
547 }
548 sim_printf ("getMFReg36(cpup, ): How'd we get here? n=%d\r\n", n);
549 return 0;
550 }
551
552 #define EISADDR_IDX(p) ((p) - cpu.currentEISinstruction.addr)
553
554 static void EISWriteCache (cpu_state_t * cpup, EISaddr * p)
555 {
556 sim_debug (DBG_TRACEEXT, & cpu_dev, "EISWriteCache addr %06o\r\n", p->cachedAddr);
557 word3 saveTRR = cpu.TPR.TRR;
558
559 if (p -> cacheValid && p -> cacheDirty)
560 {
561 if (p -> mat == viaPR)
562 {
563 cpu.TPR.TRR = p -> RNR;
564 cpu.TPR.TSR = p -> SNR;
565 cpu.cu.XSF = 0;
566 if_sim_debug (DBG_TRACEEXT, & cpu_dev)
567 {
568 for (uint i = 0; i < 8; i ++)
569 if (p->wordDirty[i])
570 {
571 sim_debug (DBG_TRACEEXT, & cpu_dev,
572 "%s: writeCache (PR) %012"PRIo64"@%o:%06o\r\n",
573 __func__, p -> cachedParagraph [i], p -> SNR, p -> cachedAddr + i);
574 }
575 }
576 { long eisaddr_idx = EISADDR_IDX (p);
577 sim_debug (DBG_TRACEEXT, & cpu_dev, "EIS %ld Write8 TRR %o TSR %05o\r\n", eisaddr_idx, cpu.TPR.TRR, cpu.TPR.TSR); }
578 for (uint i = 0; i < 8; i ++)
579 if (p->wordDirty[i])
580 {
581 Write1 (cpup, p->cachedAddr+i, p -> cachedParagraph[i], true);
582 p->wordDirty[i] = false;
583 }
584 }
585 else
586 {
587
588
589 cpu.TPR.TRR = cpu.PPR.PRR;
590 cpu.TPR.TSR = cpu.PPR.PSR;
591 cpu.cu.XSF = 0;
592
593
594 if_sim_debug (DBG_TRACEEXT, & cpu_dev)
595 {
596 for (uint i = 0; i < 8; i ++)
597 if (p->wordDirty[i])
598 {
599 sim_debug (DBG_TRACEEXT, & cpu_dev,
600 "%s: writeCache %012"PRIo64"@%o:%06o\r\n",
601 __func__, p -> cachedParagraph [i], cpu.TPR.TSR, p -> cachedAddr + i);
602 }
603 }
604 { long eisaddr_idx = EISADDR_IDX (p);
605 sim_debug (DBG_TRACEEXT, & cpu_dev, "EIS %ld Write8 NO PR TRR %o TSR %05o\r\n", eisaddr_idx, cpu.TPR.TRR, cpu.TPR.TSR); }
606 for (uint i = 0; i < 8; i ++)
607 if (p->wordDirty[i])
608 {
609 Write1 (cpup, p->cachedAddr+i, p -> cachedParagraph[i], false);
610 p->wordDirty[i] = false;
611 }
612 }
613 }
614 p -> cacheDirty = false;
615 cpu.TPR.TRR = saveTRR;
616 }
617
618 static void EISReadCache (cpu_state_t * cpup, EISaddr * p, word18 address)
619 {
620 sim_debug (DBG_TRACEEXT, & cpu_dev, "EISReadCache addr %06o\r\n", address);
621 word3 saveTRR = cpu.TPR.TRR;
622
623 address &= AMASK;
624
625 word18 paragraphAddress = address & paragraphMask;
626
627
628 if (p -> cacheValid && p -> cachedAddr == paragraphAddress)
629 {
630 return;
631 }
632
633 if (p -> cacheValid && p -> cacheDirty && p -> cachedAddr != paragraphAddress)
634 {
635 EISWriteCache (cpup, p);
636 }
637
638 if (p -> mat == viaPR)
639 {
640 cpu.TPR.TRR = p -> RNR;
641 cpu.TPR.TSR = p -> SNR;
642 cpu.cu.XSF = 0;
643 { long eisaddr_idx = EISADDR_IDX (p);
644 sim_debug (DBG_TRACEEXT, & cpu_dev, "EIS %ld Read8 TRR %o TSR %05o\r\n", eisaddr_idx, cpu.TPR.TRR, cpu.TPR.TSR); }
645 Read8 (cpup, paragraphAddress, p -> cachedParagraph, true);
646
647 if_sim_debug (DBG_TRACEEXT, & cpu_dev)
648 {
649 for (uint i = 0; i < 8; i ++)
650 sim_debug (DBG_TRACEEXT, & cpu_dev,
651 "%s: readCache (PR) %012"PRIo64"@%o:%06o\r\n",
652 __func__, p -> cachedParagraph [i], p -> SNR, paragraphAddress + i);
653 }
654 }
655 else
656 {
657
658
659 cpu.TPR.TRR = cpu.PPR.PRR;
660 cpu.TPR.TSR = cpu.PPR.PSR;
661 cpu.cu.XSF = 0;
662
663
664 { long eisaddr_idx = EISADDR_IDX (p);
665 sim_debug (DBG_TRACEEXT, & cpu_dev, "EIS %ld Read8 NO PR TRR %o TSR %05o\r\n", eisaddr_idx, cpu.TPR.TRR, cpu.TPR.TSR); }
666 Read8 (cpup, paragraphAddress, p -> cachedParagraph, false);
667 if_sim_debug (DBG_TRACEEXT, & cpu_dev)
668 {
669 for (uint i = 0; i < 8; i ++)
670 sim_debug (DBG_TRACEEXT, & cpu_dev,
671 "%s: readCache %012"PRIo64"@%o:%06o\r\n",
672 __func__, p -> cachedParagraph [i], cpu.TPR.TSR, paragraphAddress + i);
673 }
674 }
675 p -> cacheValid = true;
676 p -> cacheDirty = false;
677 for (uint i = 0; i < 8; i ++)
678 p->wordDirty[i] = false;
679 p -> cachedAddr = paragraphAddress;
680 cpu.TPR.TRR = saveTRR;
681 }
682
683 static void EISWriteIdx (cpu_state_t * cpup, EISaddr *p, uint n, word36 data, bool flush)
684 {
685 #if defined(EIS_PTR)
686 long eisaddr_idx = EISADDR_IDX (p);
687 if (eisaddr_idx < 0 || eisaddr_idx > 2) { sim_warn ("IDX1"); return }
688 sim_debug (DBG_TRACEEXT, & cpu_dev, "EISWriteIdx addr %06o n %u\r\n", cpu.du.Dk_PTR_W[eisaddr_idx], n);
689 word18 addressN = (cpu.du.Dk_PTR_W[eisaddr_idx] + n) & AMASK;
690 #else
691 sim_debug (DBG_TRACEEXT, & cpu_dev, "EISWriteIdx addr %06o n %u\r\n", p->address, n);
692 word18 addressN = p -> address + n;
693 #endif
694 addressN &= AMASK;
695
696 word18 paragraphAddress = addressN & paragraphMask;
697 word3 paragraphOffset = addressN & paragraphOffsetMask;
698
699 if (p -> cacheValid && p -> cacheDirty && p -> cachedAddr != paragraphAddress)
700 {
701 EISWriteCache (cpup, p);
702 }
703 if ((! p -> cacheValid) || p -> cachedAddr != paragraphAddress)
704 {
705 EISReadCache (cpup, p, paragraphAddress);
706 }
707 p -> cacheDirty = true;
708 p -> wordDirty[paragraphOffset] = true;
709 p -> cachedParagraph [paragraphOffset] = data;
710 p -> cachedAddr = paragraphAddress;
711
712
713
714
715 if (flush)
716 {
717 EISWriteCache (cpup, p);
718 }
719 }
720
721 static word36 EISReadIdx (cpu_state_t * cpup, EISaddr * p, uint n)
722 {
723 #if defined(EIS_PTR)
724 long eisaddr_idx = EISADDR_IDX (p);
725 if (eisaddr_idx < 0 || eisaddr_idx > 2) { sim_warn ("IDX1"); return }
726
727 sim_debug (DBG_TRACEEXT, & cpu_dev, "EISReadIdx addr %06o n %u\r\n", cpu.du.Dk_PTR_W[eisaddr_idx], n);
728 word18 addressN = (cpu.du.Dk_PTR_W[eisaddr_idx] + n) & AMASK;
729 #else
730 long eisaddr_idx = EISADDR_IDX (p);
731 sim_debug (DBG_TRACEEXT, & cpu_dev, "EISReadIdx %ld addr %06o n %u\r\n", eisaddr_idx, p->address, n);
732 word18 addressN = p -> address + n;
733 #endif
734 addressN &= AMASK;
735
736 word18 paragraphAddress = addressN & paragraphMask;
737 word3 paragraphOffset = addressN & paragraphOffsetMask;
738
739 if (p -> cacheValid && p -> cachedAddr == paragraphAddress)
740 {
741 return p -> cachedParagraph [paragraphOffset];
742 }
743 if (p -> cacheValid && p -> cacheDirty)
744 {
745 EISWriteCache (cpup, p);
746 }
747 EISReadCache (cpup, p, paragraphAddress);
748 return p -> cachedParagraph [paragraphOffset];
749 }
750
751 static word36 EISRead (cpu_state_t * cpup, EISaddr * p)
752 {
753 #if defined(EIS_PTR)
754 long eisaddr_idx = EISADDR_IDX (p);
755 if (eisaddr_idx < 0 || eisaddr_idx > 2) { sim_warn ("IDX1"); return }
756
757 sim_debug (DBG_TRACEEXT, & cpu_dev, "EISRead addr %06o\r\n", cpu.du.Dk_PTR_W[eisaddr_idx]);
758 #else
759 sim_debug (DBG_TRACEEXT, & cpu_dev, "EISRead addr %06o\r\n", p->address);
760 #endif
761 return EISReadIdx (cpup, p, 0);
762 }
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781 static void EISReadPage (cpu_state_t * cpup, EISaddr * p, uint n, word36 * data)
782 {
783 #if defined(EIS_PTR)
784 long eisaddr_idx = EISADDR_IDX (p);
785 if (eisaddr_idx < 0 || eisaddr_idx > 2) { sim_warn ("IDX1"); return }
786 word18 addressN = (cpu.du.Dk_PTR_W[eisaddr_idx] + n) & AMASK;
787 #else
788 word18 addressN = p -> address + n;
789 #endif
790 addressN &= AMASK;
791
792 sim_debug (DBG_TRACEEXT, & cpu_dev, "%s addr %06o\r\n", __func__, addressN);
793 if ((addressN & PGMK) != 0)
794 {
795 sim_warn ("EISReadPage not aligned %06o\r\n", addressN);
796 addressN &= (word18) ~PGMK;
797 }
798
799 word3 saveTRR = cpu.TPR.TRR;
800
801 if (p -> mat == viaPR)
802 {
803 cpu.TPR.TRR = p -> RNR;
804 cpu.TPR.TSR = p -> SNR;
805 cpu.cu.XSF = 0;
806 ReadPage (cpup, addressN, data, true);
807
808 if_sim_debug (DBG_TRACEEXT, & cpu_dev)
809 {
810 for (uint i = 0; i < PGSZ; i ++)
811 #if defined(EIS_PTR)
812 sim_debug (DBG_TRACEEXT, & cpu_dev,
813 "%s: (PR) %012"PRIo64"@%o:%06o\r\n",
814 __func__, data [i], cpu.TPR.TSR, addressN + i);
815 #else
816 sim_debug (DBG_TRACEEXT, & cpu_dev,
817 "%s: (PR) %012"PRIo64"@%o:%06o\r\n",
818 __func__, data [i], p -> SNR, addressN + i);
819 #endif
820 }
821 }
822 else
823 {
824
825
826 cpu.TPR.TRR = cpu.PPR.PRR;
827 cpu.TPR.TSR = cpu.PPR.PSR;
828 cpu.cu.XSF = 0;
829
830
831 ReadPage (cpup, addressN, data, false);
832 if_sim_debug (DBG_TRACEEXT, & cpu_dev)
833 {
834 for (uint i = 0; i < PGSZ; i ++)
835 sim_debug (DBG_TRACEEXT, & cpu_dev,
836 "%s: %012"PRIo64"@%o:%06o\r\n",
837 __func__, data [i], cpu.TPR.TSR, addressN + i);
838 }
839 }
840 cpu.TPR.TRR = saveTRR;
841 }
842
843 static void EISWritePage (cpu_state_t * cpup, EISaddr * p, uint n, word36 * data)
844 {
845 #if defined(EIS_PTR)
846 long eisaddr_idx = EISADDR_IDX (p);
847 if (eisaddr_idx < 0 || eisaddr_idx > 2) { sim_warn ("IDX1"); return }
848 word18 addressN = (cpu.du.Dk_PTR_W[eisaddr_idx] + n) & AMASK;
849 #else
850 word18 addressN = p -> address + n;
851 #endif
852 addressN &= AMASK;
853
854 sim_debug (DBG_TRACEEXT, & cpu_dev, "%s addr %06o\r\n", __func__, addressN);
855 if ((addressN & PGMK) != 0)
856 {
857 sim_warn ("EISWritePage not aligned %06o\r\n", addressN);
858 addressN &= (uint) ~PGMK;
859 }
860
861 word3 saveTRR = cpu.TPR.TRR;
862
863 if (p -> mat == viaPR)
864 {
865 cpu.TPR.TRR = p -> RNR;
866 cpu.TPR.TSR = p -> SNR;
867 cpu.cu.XSF = 0;
868 WritePage (cpup, addressN, data, true);
869
870 if_sim_debug (DBG_TRACEEXT, & cpu_dev)
871 {
872 for (uint i = 0; i < PGSZ; i ++)
873 #if defined(EIS_PTR)
874 sim_debug (DBG_TRACEEXT, & cpu_dev,
875 "%s: (PR) %012"PRIo64"@%o:%06o\r\n",
876 __func__, data [i], cpu.TPR.TSR, addressN + i);
877 #else
878 sim_debug (DBG_TRACEEXT, & cpu_dev,
879 "%s: (PR) %012"PRIo64"@%o:%06o\r\n",
880 __func__, data [i], p -> SNR, addressN + i);
881 #endif
882 }
883 }
884 else
885 {
886
887
888 cpu.TPR.TRR = cpu.PPR.PRR;
889 cpu.TPR.TSR = cpu.PPR.PSR;
890 cpu.cu.XSF = 0;
891
892
893 WritePage (cpup, addressN, data, false);
894 if_sim_debug (DBG_TRACEEXT, & cpu_dev)
895 {
896 for (uint i = 0; i < PGSZ; i ++)
897 sim_debug (DBG_TRACEEXT, & cpu_dev,
898 "%s: %012"PRIo64"@%o:%06o\r\n",
899 __func__, data [i], cpu.TPR.TSR, addressN + i);
900 }
901 }
902 cpu.TPR.TRR = saveTRR;
903 }
904
905 static word9 EISget469 (cpu_state_t * cpup, int k, uint i)
906 {
907 EISstruct * e = & cpu.currentEISinstruction;
908
909 uint nPos = 4;
910 #if defined(EIS_PTR3)
911 switch (cpu.du.TAk[k-1])
912 #else
913 switch (e -> TA [k - 1])
914 #endif
915 {
916 case CTA4:
917 nPos = 8;
918 break;
919
920 case CTA6:
921 nPos = 6;
922 break;
923 }
924
925 word18 address = e -> WN [k - 1];
926 uint nChars = i + e -> CN [k - 1];
927
928 address += nChars / nPos;
929 uint residue = nChars % nPos;
930
931 PNL (cpu.du.Dk_PTR_W[k-1] = address);
932 #if defined(EIS_PTR)
933 cpu.du.Dk_PTR_W[k-1] = address;
934 #else
935 e -> addr [k - 1].address = address;
936 #endif
937 word36 data = EISRead (cpup, & e -> addr [k - 1]);
938
939 word9 c = 0;
940 #if defined(EIS_PTR3)
941 switch (cpu.du.TAk[k-1])
942 #else
943 switch (e -> TA [k - 1])
944 #endif
945 {
946 case CTA4:
947 c = (word9) get4 (data, (int) residue);
948 break;
949
950 case CTA6:
951 c = (word9) get6 (data, (int) residue);
952 break;
953
954 case CTA9:
955 c = get9 (data, (int) residue);
956 break;
957 }
958 #if defined(EIS_PTR3)
959 sim_debug (DBG_TRACEEXT, & cpu_dev, "EISGet469 : k: %u TAk %u coffset %u c %o\r\n", k, cpu.du.TAk[k - 1], residue, c);
960 #else
961 sim_debug (DBG_TRACEEXT, & cpu_dev, "EISGet469 : k: %u TAk %u coffset %u c %o\r\n", k, e -> TA [k - 1], residue, c);
962 #endif
963
964 return c;
965 }
966
967 static void EISput469 (cpu_state_t * cpup, int k, uint i, word9 c469)
968 {
969 EISstruct * e = & cpu.currentEISinstruction;
970
971 uint nPos = 4;
972 #if defined(EIS_PTR3)
973 switch (cpu.du.TAk[k-1])
974 #else
975 switch (e -> TA [k - 1])
976 #endif
977 {
978 case CTA4:
979 nPos = 8;
980 break;
981
982 case CTA6:
983 nPos = 6;
984 break;
985 }
986
987 word18 address = e -> WN [k - 1];
988 uint nChars = i + e -> CN [k - 1];
989
990 address += nChars / nPos;
991 uint residue = nChars % nPos;
992
993 PNL (cpu.du.Dk_PTR_W[k-1] = address);
994 #if defined(EIS_PTR)
995 cpu.du.Dk_PTR_W[k-1] = address;
996 #else
997 e -> addr [k - 1].address = address;
998 #endif
999 word36 data = EISRead (cpup, & e -> addr [k - 1]);
1000
1001 word36 w = 0;
1002 #if defined(EIS_PTR3)
1003 switch (cpu.du.TAk[k-1])
1004 #else
1005 switch (e -> TA [k - 1])
1006 #endif
1007 {
1008 case CTA4:
1009 w = put4 (data, (int) residue, (word4) c469);
1010 break;
1011
1012 case CTA6:
1013 w = put6 (data, (int) residue, (word6) c469);
1014 break;
1015
1016 case CTA9:
1017 w = put9 (data, (int) residue, c469);
1018 break;
1019 }
1020 EISWriteIdx (cpup, & e -> addr [k - 1], 0, w, true);
1021 }
1022
1023
1024
1025
1026
1027
1028 static word9 EISget49 (cpu_state_t * cpup, EISaddr * p, int * pos, int tn)
1029 {
1030 int maxPos = tn == CTN4 ? 7 : 3;
1031
1032 if (* pos > maxPos)
1033 {
1034 * pos = 0;
1035
1036 #if defined(EIS_PTR)
1037 long eisaddr_idx = EISADDR_IDX (p);
1038 if (eisaddr_idx < 0 || eisaddr_idx > 2) { sim_warn ("IDX1"); return }
1039 cpu.du.Dk_PTR_W[eisaddr_idx] = (cpu.du.Dk_PTR_W[eisaddr_idx] + 1) & AMASK;
1040 #else
1041 p -> address = (p -> address + 1) & AMASK;
1042 #endif
1043 p -> data = EISRead (cpup, p);
1044 }
1045 else
1046 {
1047 p -> data = EISRead (cpup, p);
1048 }
1049
1050 word9 c = 0;
1051 switch (tn)
1052 {
1053 case CTN4:
1054 c = get4 (p -> data, * pos);
1055 break;
1056 case CTN9:
1057 c = get9 (p -> data, * pos);
1058 break;
1059 }
1060
1061 (* pos) ++;
1062 return c;
1063 }
1064
1065 static bool EISgetBitRWN (cpu_state_t * cpup, EISaddr * p, bool flush)
1066 {
1067 #if defined(EIS_PTR)
1068 long eisaddr_idx = EISADDR_IDX (p);
1069 if (eisaddr_idx < 0 || eisaddr_idx > 2) { sim_warn ("IDX1"); return }
1070
1071 #endif
1072 int baseCharPosn = (p -> cPos * 9);
1073 int baseBitPosn = baseCharPosn + p -> bPos;
1074 baseBitPosn += (int) cpu.du.CHTALLY;
1075
1076 int bitPosn = baseBitPosn % 36;
1077 int woff = baseBitPosn / 36;
1078
1079 #if defined(EIS_PTR)
1080 word18 saveAddr = cpu.du.Dk_PTR_W[eisaddr_idx];
1081 cpu.du.Dk_PTR_W[eisaddr_idx] += (uint) woff;
1082 cpu.du.Dk_PTR_W[eisaddr_idx] &= AMASK;
1083 #else
1084 word18 saveAddr = p -> address;
1085 p -> address += (uint) woff;
1086 #endif
1087
1088 p -> data = EISRead (cpup, p);
1089
1090 if (p -> mode == eRWreadBit)
1091 {
1092 p -> bit = getbits36_1 (p -> data, (uint) bitPosn);
1093 }
1094 else if (p -> mode == eRWwriteBit)
1095 {
1096 p -> data = setbits36_1 (p -> data, (uint) bitPosn, p -> bit);
1097
1098 EISWriteIdx (cpup, p, 0, p -> data, flush);
1099 }
1100
1101 p->last_bit_posn = bitPosn;
1102
1103 #if defined(EIS_PTR)
1104 cpu.du.Dk_PTR_W[eisaddr_idx] = saveAddr;
1105 #else
1106 p -> address = saveAddr;
1107 #endif
1108 return p -> bit;
1109 }
1110
1111 static void setupOperandDescriptorCache (cpu_state_t * cpup, int k)
1112 {
1113 EISstruct * e = & cpu.currentEISinstruction;
1114 e -> addr [k - 1]. cacheValid = false;
1115 }
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151 static void setupOperandDescriptor (cpu_state_t * cpup, int k, fault_ipr_subtype_ *mod_fault)
1152 {
1153 EISstruct * e = & cpu.currentEISinstruction;
1154 switch (k)
1155 {
1156 case 1:
1157 PNL (L68_ (DU_CYCLE_FA_I1;))
1158 PNL (L68_ (DU_CYCLE_GDLDA;))
1159 e -> MF1 = getbits36_7 (cpu.cu.IWB, 29);
1160 break;
1161 case 2:
1162 PNL (L68_ (DU_CYCLE_FA_I2;))
1163 PNL (L68_ (DU_CYCLE_GDLDB;))
1164 e -> MF2 = getbits36_7 (cpu.cu.IWB, 11);
1165 break;
1166 case 3:
1167 PNL (L68_ (DU_CYCLE_FA_I3;))
1168 PNL (L68_ (DU_CYCLE_GDLDC;))
1169 e -> MF3 = getbits36_7 (cpu.cu.IWB, 2);
1170 break;
1171 }
1172
1173 word18 MFk = e -> MF [k - 1];
1174
1175 if (MFk & MFkID)
1176 {
1177 PNL (L68_ (if (k == 1)
1178 DU_CYCLE_LDWRT1;
1179 if (k == 2)
1180 DU_CYCLE_LDWRT2;))
1181
1182 word36 opDesc = e -> op [k - 1];
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216 if (opDesc & 060)
1217 {
1218 *mod_fault |= FR_ILL_MOD;
1219
1220 }
1221
1222
1223 word18 address = GETHI (opDesc);
1224 PNL (cpu.du.Dk_PTR_W[k-1] = address);
1225 #if defined(EIS_PTR)
1226 cpu.du.Dk_PTR_W[k-1] = address;
1227 #else
1228 e -> addr [k - 1].address = address;
1229 #endif
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250 bool a = opDesc & (1 << 6);
1251 if (a)
1252 {
1253
1254
1255 word3 n = (word3) getbits18 (address, 0, 3);
1256 CPTUR (cptUsePRn + n);
1257 word15 offset = address & MASK15;
1258 address = (cpu.AR [n].WORDNO + SIGNEXT15_18 (offset)) & AMASK;
1259
1260 PNL (cpu.du.Dk_PTR_W[k-1] = address);
1261 #if defined(EIS_PTR)
1262 cpu.du.Dk_PTR_W[k-1] = address;
1263 #else
1264 e -> addr [k - 1].address = address;
1265 #endif
1266 cpu.cu.TSN_PRNO[k-1] = n;
1267 cpu.cu.TSN_VALID[k-1] = 1;
1268 e -> addr [k - 1].SNR = cpu.PR [n].SNR;
1269 e -> addr [k - 1].RNR = max3 (cpu.PR [n].RNR,
1270 cpu.TPR.TRR,
1271 cpu.PPR.PRR);
1272
1273 e -> addr [k - 1].mat = viaPR;
1274 sim_debug (DBG_TRACEEXT, & cpu_dev, "AR n %u k %u\r\n", n, k - 1);
1275 }
1276 else
1277 {
1278 e->addr [k - 1].mat = OperandRead;
1279 sim_debug (DBG_TRACEEXT, & cpu_dev, "No ARb %u\r\n", k - 1);
1280 }
1281
1282
1283
1284
1285
1286
1287 uint reg = opDesc & 017;
1288
1289 address += getMFReg18 (cpup, reg, false, true, mod_fault);
1290 address &= AMASK;
1291
1292 PNL (cpu.du.Dk_PTR_W[k-1] = address);
1293
1294 #if defined(EIS_PTR)
1295 cpu.du.Dk_PTR_W[k-1] = address;
1296 #else
1297 e -> addr [k - 1].address = address;
1298 #endif
1299
1300
1301 e -> op [k - 1] = EISRead (cpup, & e -> addr [k - 1]);
1302 }
1303 else
1304 {
1305 e->addr [k - 1].mat = OperandRead;
1306 sim_debug (DBG_TRACEEXT, & cpu_dev, "No ARa %u\r\n", k - 1);
1307 }
1308 setupOperandDescriptorCache (cpup, k);
1309 }
1310
1311 void setupEISoperands (cpu_state_t * cpup)
1312 {
1313 PNL (cpu.du.POP = 0);
1314 PNL (cpu.du.POL = 0);
1315
1316 #if defined(EIS_SETUP)
1317 for (int i = 0; i < 3; i ++)
1318 {
1319 if (i < cpu.currentInstruction.info -> ndes)
1320 setupOperandDescriptor (cpup, i + 1);
1321 else
1322 setupOperandDescriptorCache (cpup, i + 1);
1323 }
1324 #endif
1325 }
1326
1327 static void parseAlphanumericOperandDescriptor (cpu_state_t * cpup, uint k, uint useTA, bool allowDU, fault_ipr_subtype_ *mod_fault)
1328 {
1329 EISstruct * e = & cpu.currentEISinstruction;
1330 word18 MFk = e -> MF [k - 1];
1331
1332 PNL (L68_ (if (k == 1)
1333 DU_CYCLE_ANLD1;
1334 else if (k == 2)
1335 DU_CYCLE_ANLD2;
1336 else if (k == 3)
1337 DU_CYCLE_ANSTR;))
1338
1339 PNL (cpu.du.POP = 1);
1340
1341 word36 opDesc = e -> op [k - 1];
1342
1343 word8 ARn_CHAR = 0;
1344 word6 ARn_BITNO = 0;
1345
1346 word18 address = GETHI (opDesc);
1347
1348 #if defined(EIS_PTR3)
1349 if (useTA != k)
1350 cpu.du.TAk[k-1] = cpu.du.TAk[useTA-1];
1351 else
1352 cpu.du.TAk[k-1] = getbits36_2 (opDesc, 21);
1353 #else
1354 if (useTA != k)
1355 e -> TA [k - 1] = e -> TA [useTA - 1];
1356 else
1357 e -> TA [k - 1] = getbits36_2 (opDesc, 21);
1358 #endif
1359
1360 #if defined(PANEL68)
1361 if (k == 1)
1362 {
1363 switch (e->TA[0])
1364 {
1365 case CTA9:
1366 cpu.dataMode = 0102;
1367 cpu.ou.opsz = is_9 >> 12;
1368 break;
1369 case CTA6:
1370 cpu.dataMode = 0042;
1371 cpu.ou.opsz = is_6 >> 12;
1372 break;
1373 case CTA4:
1374 cpu.dataMode = 0022;
1375 cpu.ou.opsz = is_4 >> 12;
1376 break;
1377 }
1378 }
1379 #endif
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403 if (MFk & MFkAR)
1404 {
1405
1406
1407
1408 word3 n = (word3) getbits18 (address, 0, 3);
1409 CPTUR (cptUsePRn + n);
1410 word18 offset = SIGNEXT15_18 ((word15) address);
1411 address = (cpu.AR [n].WORDNO + offset) & AMASK;
1412
1413 ARn_CHAR = GET_AR_CHAR (n);
1414 ARn_BITNO = GET_AR_BITNO (n);
1415
1416 cpu.cu.TSN_PRNO[k-1] = n;
1417 cpu.cu.TSN_VALID[k-1] = 1;
1418 e -> addr [k - 1].SNR = cpu.PR [n].SNR;
1419 e -> addr [k - 1].RNR = max3 (cpu.PR [n].RNR, cpu.TPR.TRR, cpu.PPR.PRR);
1420
1421 e -> addr [k - 1].mat = viaPR;
1422 sim_debug (DBG_TRACEEXT, & cpu_dev, "AR n %u k %u\r\n", n, k - 1);
1423 }
1424
1425 PNL (cpu.du.POL = 1);
1426
1427 uint CN = getbits36_3 (opDesc, 18);
1428
1429 sim_debug (DBG_TRACEEXT, & cpu_dev, "initial CN%u %u\r\n", k, CN);
1430
1431 if (MFk & MFkRL)
1432 {
1433 uint reg = opDesc & 017;
1434
1435 e -> N [k - 1] = (uint) getMFReg36 (cpup, reg, false, false, mod_fault);
1436 #if defined(EIS_PTR3)
1437 switch (cpu.du.TAk[k-1])
1438 #else
1439 switch (e -> TA [k - 1])
1440 #endif
1441 {
1442 case CTA4:
1443 e -> N [k - 1] &= 017777777;
1444 break;
1445
1446 case CTA6:
1447 case CTA9:
1448 e -> N [k - 1] &= 07777777;
1449 break;
1450
1451 default:
1452 L68_ (doFault (FAULT_IPR, fst_ill_proc, "parseAlphanumericOperandDescriptor TA 3");)
1453
1454 *mod_fault |= FR_ILL_PROC;
1455 break;
1456 }
1457 }
1458 else
1459 e -> N [k - 1] = opDesc & 07777;
1460
1461
1462
1463
1464 sim_debug (DBG_TRACEEXT, & cpu_dev, "N%u %o\r\n", k, e->N[k-1]);
1465
1466 word36 r = getMFReg36 (cpup, MFk & 017, allowDU, true, mod_fault);
1467
1468 if ((MFk & 017) == 4)
1469 {
1470 address += r;
1471 address &= AMASK;
1472 r = 0;
1473 }
1474
1475
1476
1477
1478 uint effBITNO = 0;
1479 uint effCHAR = 0;
1480 uint effWORDNO = 0;
1481
1482 #if defined(EIS_PTR3)
1483 switch (cpu.du.TAk[k-1])
1484 #else
1485 switch (e -> TA [k - 1])
1486 #endif
1487 {
1488 case CTA4:
1489 {
1490
1491
1492
1493
1494 uint arn_char4 = ARn_CHAR * 2u + (ARn_BITNO >= 5u ? 1u : 0u);
1495
1496
1497
1498 uint nchars = address * 8 + (uint) r + arn_char4 + CN;
1499
1500 effWORDNO = nchars / 8;
1501 effCHAR = nchars % 8;
1502
1503 effBITNO = (nchars & 1) ? 5 : 0;
1504
1505 effWORDNO &= AMASK;
1506
1507 e -> CN [k - 1] = effCHAR;
1508 e -> WN [k - 1] = effWORDNO;
1509
1510 sim_debug (DBG_TRACEEXT, & cpu_dev, "CN%d set to %d by CTA4\r\n",
1511 k, e -> CN [k - 1]);
1512 }
1513 break;
1514
1515 case CTA6:
1516 if (CN >= 6) {
1517 L68_ (doFault (FAULT_IPR, fst_ill_proc, "parseAlphanumericOperandDescriptor TAn CTA6 CN >= 6");)
1518
1519 *mod_fault |= FR_ILL_PROC;
1520 }
1521 {
1522
1523
1524
1525
1526
1527
1528
1529 uint rbits = (k == 3 &&
1530 cpu.currentInstruction.opcode == 024 &&
1531 cpu.currentInstruction.opcodeX == 1) ? 9u : 6u;
1532 effBITNO = (9u * ARn_CHAR + rbits * r + ARn_BITNO) % 9u;
1533 effCHAR = ((6u * CN +
1534 9u * ARn_CHAR +
1535 rbits * r + ARn_BITNO) % 36u) / 6u;
1536 effWORDNO = (uint) (address +
1537 (6u * CN +
1538 9u * ARn_CHAR +
1539 rbits * r +
1540 ARn_BITNO) / 36u);
1541 }
1542 effWORDNO &= AMASK;
1543
1544 e -> CN [k - 1] = effCHAR;
1545 e -> WN [k - 1] = effWORDNO;
1546 sim_debug (DBG_TRACEEXT, & cpu_dev, "CN%d set to %d by CTA6\r\n",
1547 k, e -> CN [k - 1]);
1548 break;
1549
1550 case CTA9:
1551 if (CN & 01) {
1552 L68_ (doFault(FAULT_IPR, fst_ill_proc, "parseAlphanumericOperandDescriptor CTA9 & CN odd");)
1553
1554 *mod_fault |= FR_ILL_PROC;
1555 }
1556 CN = (CN >> 1);
1557
1558 effBITNO = 0;
1559 effCHAR = (CN + ARn_CHAR + r) % 4;
1560 sim_debug (DBG_TRACEEXT, & cpu_dev,
1561 "effCHAR %d = (CN %d + ARn_CHAR %d + r %"PRId64") %% 4)\r\n",
1562 effCHAR, CN, ARn_CHAR, r);
1563
1564
1565 effWORDNO = (uint) (address +
1566 ((9u * CN +
1567 9u * ARn_CHAR +
1568 9u * r) / 36u));
1569 effWORDNO &= AMASK;
1570
1571 e -> CN [k - 1] = effCHAR;
1572 e -> WN [k - 1] = effWORDNO;
1573 sim_debug (DBG_TRACEEXT, & cpu_dev, "CN%d set to %d by CTA9\r\n",
1574 k, e -> CN [k - 1]);
1575 break;
1576
1577 default:
1578 L68_ (doFault (FAULT_IPR, fst_ill_proc, "parseAlphanumericOperandDescriptor TA1 3");)
1579
1580 *mod_fault |= FR_ILL_PROC;
1581 break;
1582 }
1583
1584 EISaddr * a = & e -> addr [k - 1];
1585 PNL (cpu.du.Dk_PTR_W[k-1] = effWORDNO);
1586 #if defined(EIS_PTR)
1587 cpu.du.Dk_PTR_W[k-1] = effWORDNO;
1588 #else
1589 a -> address = effWORDNO;
1590 #endif
1591 a -> cPos= (int) effCHAR;
1592 a -> bPos = (int) effBITNO;
1593
1594 #if !defined(EIS_PTR3)
1595
1596 a -> TA = (int) e -> TA [k - 1];
1597 #endif
1598 }
1599
1600 static void parseArgOperandDescriptor (cpu_state_t * cpup, uint k, fault_ipr_subtype_ *mod_fault)
1601 {
1602 PNL (L68_ (if (k == 1)
1603 DU_CYCLE_NLD1;
1604 else if (k == 2)
1605 DU_CYCLE_NLD2;
1606 else if (k == 3)
1607 DU_CYCLE_GSTR;))
1608
1609 EISstruct * e = & cpu.currentEISinstruction;
1610 word36 opDesc = e -> op [k - 1];
1611 word18 y = GETHI (opDesc);
1612 word1 yA = GET_A (opDesc);
1613
1614 uint yREG = opDesc & 0xf;
1615
1616 word36 r = getMFReg36 (cpup, yREG, false, true, mod_fault);
1617
1618 word8 ARn_CHAR = 0;
1619 word6 ARn_BITNO = 0;
1620
1621 PNL (cpu.du.POP = 1);
1622
1623 if (yA)
1624 {
1625
1626
1627
1628 word3 n = GET_ARN (opDesc);
1629 CPTUR (cptUsePRn + n);
1630 word15 offset = y & MASK15;
1631 y = (cpu.AR [n].WORDNO + SIGNEXT15_18 (offset)) & AMASK;
1632
1633 ARn_CHAR = GET_AR_CHAR (n);
1634 ARn_BITNO = GET_AR_BITNO (n);
1635
1636 cpu.cu.TSN_PRNO[k-1] = n;
1637 cpu.cu.TSN_VALID[k-1] = 1;
1638 e -> addr [k - 1].SNR = cpu.PR[n].SNR;
1639 e -> addr [k - 1].RNR = max3 (cpu.PR [n].RNR, cpu.TPR.TRR, cpu.PPR.PRR);
1640 e -> addr [k - 1].mat = viaPR;
1641 }
1642
1643 y += ((9u * ARn_CHAR + 36u * r + ARn_BITNO) / 36u);
1644 y &= AMASK;
1645
1646 PNL (cpu.du.Dk_PTR_W[k-1] = y);
1647
1648 #if defined(EIS_PTR)
1649 cpu.du.Dk_PTR_W[k-1] = y;
1650 #else
1651 e -> addr [k - 1].address = y;
1652 #endif
1653 }
1654
1655 static void parseNumericOperandDescriptor (cpu_state_t * cpup, int k, fault_ipr_subtype_ *mod_fault)
1656 {
1657 PNL (L68_ (if (k == 1)
1658 DU_CYCLE_NLD1;
1659 else if (k == 2)
1660 DU_CYCLE_NLD2;
1661 else if (k == 3)
1662 DU_CYCLE_GSTR;))
1663
1664 EISstruct * e = & cpu.currentEISinstruction;
1665 word18 MFk = e->MF[k-1];
1666
1667 PNL (cpu.du.POP = 1);
1668
1669 word36 opDesc = e->op[k-1];
1670
1671 word8 ARn_CHAR = 0;
1672 word6 ARn_BITNO = 0;
1673
1674 word18 address = GETHI(opDesc);
1675 if (MFk & MFkAR)
1676 {
1677
1678
1679
1680 word3 n = (word3) getbits18 (address, 0, 3);
1681 CPTUR (cptUsePRn + n);
1682 word15 offset = address & MASK15;
1683 address = (cpu.AR[n].WORDNO + SIGNEXT15_18(offset)) & AMASK;
1684
1685 ARn_CHAR = GET_AR_CHAR (n);
1686 ARn_BITNO = GET_AR_BITNO (n);
1687
1688 cpu.cu.TSN_PRNO[k-1] = n;
1689 cpu.cu.TSN_VALID[k-1] = 1;
1690 e->addr[k-1].SNR = cpu.PR[n].SNR;
1691 e->addr[k-1].RNR = max3(cpu.PR[n].RNR, cpu.TPR.TRR, cpu.PPR.PRR);
1692
1693 e->addr[k-1].mat = viaPR;
1694 }
1695
1696 PNL (cpu.du.POL = 1);
1697
1698 word3 CN = getbits36_3 (opDesc, 18);
1699 e->TN[k-1] = getbits36_1 (opDesc, 21);
1700
1701 #if defined(PANEL68)
1702 if (k == 1)
1703 {
1704 if (e->TN[0])
1705 cpu.dataMode = 0021;
1706 else
1707 cpu.dataMode = 0101;
1708 }
1709 #endif
1710
1711 e->S[k-1] = getbits36_2 (opDesc, 22);
1712 e->SF[k-1] = SIGNEXT6_int (getbits36_6 (opDesc, 24));
1713
1714
1715
1716
1717
1718
1719
1720 if (MFk & MFkRL)
1721 {
1722 uint reg = opDesc & 017;
1723 e->N[k-1] = getMFReg18 (cpup,reg, false, false, mod_fault) & 077;
1724 }
1725 else
1726 e->N[k-1] = opDesc & 077;
1727
1728 sim_debug (DBG_TRACEEXT, & cpu_dev, "parseNumericOperandDescriptor(cpup, ): N%u %0o\r\n", k, e->N[k-1]);
1729
1730 word36 r = getMFReg36(cpup, MFk & 017, false, true, mod_fault);
1731 if ((MFk & 017) == 4)
1732 {
1733 address += r;
1734 address &= AMASK;
1735 r = 0;
1736 }
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755 uint effBITNO = 0;
1756 uint effCHAR = 0;
1757 uint effWORDNO = 0;
1758
1759
1760
1761
1762
1763
1764 switch (e->TN[k-1])
1765 {
1766 case CTN4:
1767 {
1768
1769
1770
1771
1772 uint arn_char4 = ARn_CHAR * 2u + (ARn_BITNO >= 5u ? 1u : 0u);
1773
1774
1775
1776
1777
1778 uint nchars = (uint) (address * 8u + r + arn_char4 + CN);
1779
1780 effWORDNO = nchars / 8u;
1781 effCHAR = nchars % 8u;
1782 effBITNO = (nchars & 1u) ? 5u : 0u;
1783 effWORDNO &= AMASK;
1784
1785 e->CN[k-1] = effCHAR;
1786 }
1787 break;
1788
1789 case CTN9:
1790 if (CN & 1u) {
1791 L68_ (doFault(FAULT_IPR, fst_ill_proc, "parseNumericOperandDescriptor CTA9 & CN odd");)
1792
1793 *mod_fault |= FR_ILL_PROC;
1794 }
1795 CN = (CN >> 1u) & 03u;
1796
1797 effBITNO = 0;
1798 effCHAR = ((word36) CN + (word36) ARn_CHAR + r) % 4u;
1799
1800 effWORDNO = (uint) (address + (9u*CN + 9u*ARn_CHAR + 9u*r) / 36);
1801 effWORDNO &= AMASK;
1802
1803 e->CN[k-1] = effCHAR;
1804
1805 break;
1806 default:
1807 #if defined(EIS_PTR3)
1808 sim_printf ("parseNumericOperandDescriptor(cpup, ta=%d) How'd we get here 2?\r\n",
1809 cpu.du.TAk[k-1]);
1810 #else
1811 sim_printf ("parseNumericOperandDescriptor(cpup, ta=%d) How'd we get here 2?\r\n",
1812 e->TA[k-1]);
1813 #endif
1814 break;
1815 }
1816
1817 EISaddr *a = &e->addr[k-1];
1818 PNL (cpu.du.Dk_PTR_W[k-1] = effWORDNO);
1819 #if defined(EIS_PTR)
1820 cpu.du.Dk_PTR_W[k-1] = effWORDNO;
1821 #else
1822 a->address = effWORDNO;
1823 #endif
1824 a->cPos = (int) effCHAR;
1825 a->bPos = (int) effBITNO;
1826
1827
1828 a->TN = (int) e->TN[k-1];
1829
1830 #if defined(EIS_PTR)
1831 sim_debug (DBG_TRACEEXT, & cpu_dev,
1832 "parseNumericOperandDescriptor(cpup, ): address:%06o cPos:%d bPos:%d N%u %u\r\n",
1833 cpu.du.Dk_PTR_W[k-1], a->cPos, a->bPos, k, e->N[k-1]);
1834 #else
1835 sim_debug (DBG_TRACEEXT, & cpu_dev,
1836 "parseNumericOperandDescriptor(cpup, ): address:%06o cPos:%d bPos:%d N%u %u\r\n",
1837 a->address, a->cPos, a->bPos, k, e->N[k-1]);
1838 #endif
1839 }
1840
1841 static void parseBitstringOperandDescriptor (cpu_state_t * cpup, int k, fault_ipr_subtype_ *mod_fault)
1842 {
1843 PNL (L68_ (if (k == 1)
1844 DU_CYCLE_ANLD1;
1845 else if (k == 2)
1846 DU_CYCLE_ANLD2;
1847 else if (k == 3)
1848 DU_CYCLE_ANSTR;))
1849
1850 EISstruct * e = & cpu.currentEISinstruction;
1851 word18 MFk = e->MF[k-1];
1852 word36 opDesc = e->op[k-1];
1853
1854 #if defined(PANEL68)
1855 if (k == 1)
1856 cpu.dataMode = 0010;
1857 #endif
1858 word8 ARn_CHAR = 0;
1859 word6 ARn_BITNO = 0;
1860
1861 PNL (cpu.du.POP = 1);
1862
1863 word18 address = GETHI(opDesc);
1864 if (MFk & MFkAR)
1865 {
1866
1867
1868
1869 word3 n = (word3) getbits18 (address, 0, 3);
1870 CPTUR (cptUsePRn + n);
1871 word15 offset = address & MASK15;
1872 address = (cpu.AR[n].WORDNO + SIGNEXT15_18(offset)) & AMASK;
1873
1874 sim_debug (DBG_TRACEEXT, & cpu_dev, "bitstring k %d AR%d\r\n", k, n);
1875
1876 ARn_CHAR = GET_AR_CHAR (n);
1877 ARn_BITNO = GET_AR_BITNO (n);
1878 cpu.cu.TSN_PRNO[k-1] = n;
1879 cpu.cu.TSN_VALID[k-1] = 1;
1880 e->addr[k-1].SNR = cpu.PR[n].SNR;
1881 e->addr[k-1].RNR = max3(cpu.PR[n].RNR, cpu.TPR.TRR, cpu.PPR.PRR);
1882 e->addr[k-1].mat = viaPR;
1883 }
1884 PNL (cpu.du.POL = 1);
1885
1886
1887
1888
1889
1890 if (MFk & MFkRL)
1891 {
1892 uint reg = opDesc & 017;
1893 e->N[k-1] = getMFReg36(cpup, reg, false, false, mod_fault) & 077777777;
1894 sim_debug (DBG_TRACEEXT, & cpu_dev, "bitstring k %d RL reg %u val %"PRIo64"\r\n", k, reg, (word36)e->N[k-1]);
1895 }
1896 else
1897 {
1898 e ->N[k-1] = opDesc & 07777;
1899 }
1900
1901 sim_debug (DBG_TRACEEXT, & cpu_dev, "bitstring k %d opdesc %012"PRIo64"\r\n", k, opDesc);
1902 sim_debug (DBG_TRACEEXT, & cpu_dev, "N%u %u\r\n", k, e->N[k-1]);
1903
1904 word4 B = getbits36_4(opDesc, 20);
1905 word2 C = getbits36_2 (opDesc, 18);
1906
1907 if (B >= 9) {
1908 L68_ (doFault (FAULT_IPR, fst_ill_proc, "parseBitstringOperandDescriptor B >= 9");)
1909
1910 *mod_fault |= FR_ILL_PROC;
1911 }
1912
1913 word36 r = getMFReg36(cpup, MFk & 017, false, true, mod_fault);
1914 if ((MFk & 017) == 4)
1915 {
1916
1917
1918 address += r;
1919 address &= AMASK;
1920 r = 0;
1921 }
1922
1923 uint effBITNO = (9u*ARn_CHAR + r + ARn_BITNO + B + 9u*C) % 9u;
1924 uint effCHAR = ((9u*ARn_CHAR + r + ARn_BITNO + B + 9u*C) % 36u) / 9u;
1925 uint effWORDNO = (uint) (address + (9u*ARn_CHAR + r + ARn_BITNO + B + 9u*C) / 36u);
1926 effWORDNO &= AMASK;
1927
1928 e->B[k-1] = effBITNO;
1929 e->C[k-1] = effCHAR;
1930
1931 EISaddr *a = &e->addr[k-1];
1932 PNL (cpu.du.Dk_PTR_W[k-1] = effWORDNO);
1933 #if defined(EIS_PTR)
1934 cpu.du.Dk_PTR_W[k-1] = effWORDNO;
1935 #else
1936 a->address = effWORDNO;
1937 #endif
1938 a->cPos = (int) effCHAR;
1939 a->bPos = (int) effBITNO;
1940 }
1941
1942 static void cleanupOperandDescriptor (cpu_state_t * cpup, int k)
1943 {
1944 EISstruct * e = & cpu.currentEISinstruction;
1945 if (e -> addr [k - 1].cacheValid && e -> addr [k - 1].cacheDirty)
1946 {
1947 EISWriteCache(cpup, & e -> addr [k - 1]);
1948 }
1949 e -> addr [k - 1].cacheDirty = false;
1950 }
1951
1952
1953
1954 bool tandd_eis_interruptible (cpu_state_t * cpup)
1955 {
1956 DCDstruct * i = & cpu.currentInstruction;
1957 if (! i -> opcodeX)
1958 return false;
1959 switch (i -> opcode)
1960 {
1961 case 0100:
1962 case 0101:
1963 case 0160:
1964 case 0106:
1965 case 0120:
1966 case 0121:
1967 case 0124:
1968 case 0125:
1969 case 0164:
1970 case 0165:
1971 case 0060:
1972 case 0061:
1973 case 0064:
1974 case 0065:
1975 case 0066:
1976 return true;
1977 }
1978 return false;
1979 }
1980
1981
1982 #define TDPER(ta) ((ta) == CTA6 ? 6u : (ta) == CTA4 ? 8u : 4u)
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992 void tandd_eis_sample (cpu_state_t * cpup, uint unit, uint perWord)
1993 {
1994 if (! cpu.tweaks.tandd_mode || cpu.currentInstruction.i ||
1995 unit <= cpu.tanddEISstart || unit % (2 * perWord))
1996 return;
1997 if (++ cpu.rTRlsb >= 4)
1998 {
1999 cpu.rTRlsb = 0;
2000 cpu.rTR --;
2001 cpu.lufTicks ++;
2002 cpu.tanddTRTicks ++;
2003 }
2004 if (cpu.rTR & ~MASK27)
2005 {
2006 cpu.rTR &= MASK27;
2007 if (cpu.tweaks.tro_enable)
2008 setG7fault (current_running_cpu_idx, FAULT_TRO);
2009 }
2010 advanceG7Faults (cpup);
2011 bool noCheckTR = is_priv_mode (cpup);
2012
2013
2014
2015 bool g7 = noCheckTR ? (cpu.g7Faults & ~(1u << FAULT_TRO)) != 0
2016 : cpu.g7Faults != 0;
2017 if (! g7 && ! sample_interrupts (cpup))
2018 return;
2019 for (int k = 1; k <= 3; k ++)
2020 cleanupOperandDescriptor (cpup, k);
2021 cpu.du.CHTALLY = unit;
2022 SC_I_MIF (1);
2023 if (g7)
2024 doG7Fault (cpup, ! noCheckTR);
2025 cpu.interrupt_flag = true;
2026 cpu.cycle = INTERRUPT_cycle;
2027 longjmp (cpu.jmpMain, JMP_REENTRY);
2028 }
2029
2030
2031
2032 #define n4bits (1 << 23)
2033
2034
2035 #define n4chars (1 << 21)
2036
2037
2038 #define nxbits ((1 << 18) * 36)
2039
2040
2041 static unsigned int cntFromBit[36] = {
2042 0, 0, 0, 0, 0, 1, 1, 1, 1,
2043 2, 2, 2, 2, 2, 3, 3, 3, 3,
2044 4, 4, 4, 4, 4, 5, 5, 5, 5,
2045 6, 6, 6, 6, 6, 7, 7, 7, 7
2046 };
2047
2048 static word6 bitFromCnt[8] = {1, 5, 10, 14, 19, 23, 28, 32};
2049
2050 void a4bd (cpu_state_t * cpup)
2051 {
2052
2053
2054 uint ARn = GET_ARN (cpu.cu.IWB);
2055 CPTUR (cptUsePRn + ARn);
2056 int32_t address = SIGNEXT15_32 (GET_OFFSET (cpu.cu.IWB));
2057
2058
2059
2060 word4 reg = GET_TD (cpu.cu.IWB);
2061
2062
2063 word36 ur = getCrAR (cpup, reg);
2064 int32 r = SIGNEXT22_32 ((word22) ur);
2065
2066
2067
2068 uint augend = 0;
2069 if (GET_A (cpu.cu.IWB))
2070 {
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080 augend = cpu.AR[ARn].WORDNO * 8u + GET_AR_CHAR (ARn) * 2u;
2081
2082
2083 if (GET_AR_BITNO (ARn) >= 5u)
2084 augend ++;
2085 }
2086
2087
2088
2089
2090 int32_t addend = address * 8 + r;
2091
2092
2093
2094
2095 int32_t sum = (int32_t) augend + addend;
2096
2097
2098
2099
2100 while (sum < 0)
2101 sum += n4chars;
2102 sum = sum % n4chars;
2103
2104
2105
2106 cpu.AR[ARn].WORDNO = (word18) (sum / 8) & AMASK;
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122 uint char4no = (uint) (sum % 8);
2123
2124
2125
2126 SET_AR_CHAR_BITNO (ARn, (word2) (char4no / 2), (char4no % 2) ? 5 : 0);
2127 #if defined(TESTING)
2128 HDBGRegARW (ARn, "a4bd");
2129 #endif
2130
2131
2132
2133
2134 }
2135
2136 void s4bd (cpu_state_t * cpup)
2137 {
2138 uint ARn = GET_ARN (cpu.cu.IWB);
2139 CPTUR (cptUsePRn + ARn);
2140 int32_t address = SIGNEXT15_32 (GET_OFFSET (cpu.cu.IWB));
2141 word4 reg = GET_TD (cpu.cu.IWB);
2142
2143
2144 word36 ur = getCrAR (cpup, reg);
2145 int32 r = SIGNEXT22_32 ((word22) ur);
2146
2147 uint minuend = 0;
2148 if (GET_A (cpu.cu.IWB))
2149 {
2150
2151 minuend = cpu.AR [ARn].WORDNO * 32 + cntFromBit [GET_AR_CHAR (ARn) * 9 + GET_AR_BITNO (ARn)];
2152
2153 minuend = minuend & (unsigned int) ~3;
2154 }
2155 int32_t subtractend = address * 32 + r * 4;
2156 int32_t difference = (int32_t) minuend - subtractend;
2157
2158
2159 while (difference < 0)
2160 difference += n4bits;
2161 difference = difference % n4bits;
2162
2163 cpu.AR [ARn].WORDNO = (word18) (difference / 32) & AMASK;
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174 uint bitno = (uint) (difference % 32);
2175
2176
2177 SET_AR_CHAR_BITNO (ARn, bitFromCnt[bitno % 8] / 9, bitFromCnt[bitno % 8] % 9);
2178 #if defined(TESTING)
2179 HDBGRegARW (ARn, "s4bd");
2180 #endif
2181 }
2182
2183 void axbd (cpu_state_t * cpup, uint sz)
2184 {
2185 uint ARn = GET_ARN (cpu.cu.IWB);
2186 CPTUR (cptUsePRn + ARn);
2187 int32_t address = SIGNEXT15_32 (GET_OFFSET (cpu.cu.IWB));
2188 word6 reg = GET_TD (cpu.cu.IWB);
2189
2190
2191 word36 rcnt = getCrAR (cpup, reg);
2192 int32_t r;
2193
2194 if (sz == 1)
2195 r = SIGNEXT24_32 ((word24) rcnt);
2196 else if (sz == 4)
2197 r = SIGNEXT22_32 ((word22) rcnt);
2198 else if (sz == 6)
2199 r = SIGNEXT21_32 ((word21) rcnt);
2200 else if (sz == 9)
2201 r = SIGNEXT21_32 ((word21) rcnt);
2202 else
2203 r = SIGNEXT18_32 ((word18) rcnt);
2204
2205 sim_debug (DBG_TRACEEXT|DBG_CAC, & cpu_dev,
2206 "axbd sz %d ARn 0%o address 0%o reg 0%o r 0%o\r\n",
2207 sz, ARn, address, reg, r);
2208
2209 uint augend = 0;
2210 if (GET_A (cpu.cu.IWB))
2211 {
2212 sim_debug (DBG_TRACEEXT|DBG_CAC, & cpu_dev,
2213 "axbd ARn %d WORDNO %o CHAR %o BITNO %0o %d.\r\n",
2214 ARn, cpu.PAR[ARn].WORDNO, GET_AR_CHAR (ARn),
2215 GET_AR_BITNO (ARn), GET_AR_BITNO (ARn));
2216 augend = cpu.AR[ARn].WORDNO * 36u + GET_AR_CHAR (ARn) * 9u + GET_AR_BITNO (ARn);
2217 }
2218 sim_debug (DBG_TRACEEXT|DBG_CAC, & cpu_dev,
2219 "axbd augend 0%o\r\n",
2220 augend);
2221
2222
2223 if (sz == 9 || GET_A (cpu.cu.IWB))
2224 {
2225 augend = (augend / sz) * sz;
2226 sim_debug (DBG_TRACEEXT|DBG_CAC, & cpu_dev,
2227 "axbd force augend 0%o\r\n",
2228 augend);
2229 }
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239 int32_t addend = address * 36 + r * (int32_t) sz;
2240 int32_t sum = (int32_t) augend + addend;
2241
2242
2243 while (sum < 0)
2244 sum += nxbits;
2245 sum = sum % nxbits;
2246
2247 sim_debug (DBG_TRACEEXT|DBG_CAC, & cpu_dev, "axbd augend 0%o addend 0%o sum 0%o\r\n", augend, addend, sum);
2248
2249 cpu.AR [ARn].WORDNO = (word18) (sum / 36) & AMASK;
2250
2251 #if defined(TESTING)
2252 HDBGRegARR (ARn, "axbd");
2253 #endif
2254 SET_AR_CHAR_BITNO (ARn, (word2)((sum % 36) / 9), (word2)(sum % 9));
2255 #if defined(TESTING)
2256 HDBGRegARW (ARn, "axbd");
2257 #endif
2258 }
2259
2260
2261 void abd (cpu_state_t * cpup)
2262 {
2263 uint ARn = GET_ARN (cpu.cu.IWB);
2264 CPTUR (cptUsePRn + ARn);
2265
2266 word18 address = SIGNEXT15_18 (GET_OFFSET (cpu.cu.IWB));
2267
2268
2269 word4 reg = (word4) GET_TD (cpu.cu.IWB);
2270
2271 word24 r = getCrAR (cpup, (word4) reg) & MASK24;
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281 if (GET_AR_BITNO (ARn) > 8)
2282 SET_AR_CHAR_BITNO (ARn, GET_AR_CHAR (ARn), 8);
2283
2284 if (GET_A (cpu.cu.IWB))
2285 {
2286
2287
2288
2289 word24 bits = 9u * GET_AR_CHAR (ARn) + GET_AR_BITNO (ARn) + r;
2290
2291
2292 cpu.AR[ARn].WORDNO = (cpu.AR[ARn].WORDNO + address +
2293 bits / 36) & MASK18;
2294 if (r % 36)
2295 {
2296
2297
2298 SET_AR_CHAR_BITNO (ARn, (bits % 36) / 9,
2299 bits % 9);
2300 }
2301 }
2302 else
2303 {
2304
2305
2306 cpu.AR[ARn].WORDNO = (address + r / 36) & MASK18;
2307 if (r % 36)
2308 {
2309
2310
2311 SET_AR_CHAR_BITNO (ARn, (r % 36) / 9,
2312 r % 9);
2313 }
2314 }
2315 # if defined(TESTING)
2316 HDBGRegARW (ARn, "abd");
2317 # endif
2318
2319
2320
2321
2322 }
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471 void awd (cpu_state_t * cpup)
2472 {
2473 uint ARn = GET_ARN (cpu.cu.IWB);
2474 CPTUR (cptUsePRn + ARn);
2475 int32_t address = SIGNEXT15_32 (GET_OFFSET (cpu.cu.IWB));
2476
2477
2478 word4 reg = (word4) GET_TD (cpu.cu.IWB);
2479
2480
2481 int32_t r = (int32_t) (getCrAR (cpup, reg) & MASK18);
2482 r = SIGNEXT18_32 ((word18) r);
2483
2484 sim_debug (DBG_TRACEEXT|DBG_CAC, & cpu_dev,
2485 "awd ARn 0%o address 0%o reg 0%o r 0%o\r\n",
2486 ARn, address, reg, r);
2487
2488 uint augend = 0;
2489 if (GET_A (cpu.cu.IWB))
2490 {
2491 sim_debug (DBG_TRACEEXT|DBG_CAC, & cpu_dev,
2492 "awd ARn %d WORDNO %o CHAR %o BITNO %0o %d.\r\n",
2493 ARn, cpu.PAR[ARn].WORDNO, GET_AR_CHAR (ARn),
2494 GET_AR_BITNO (ARn), GET_AR_BITNO (ARn));
2495
2496
2497 augend = cpu.AR [ARn].WORDNO;
2498 }
2499
2500 sim_debug (DBG_TRACEEXT|DBG_CAC, & cpu_dev,
2501 "awd augend 0%o\r\n",
2502 augend);
2503
2504 int32_t addend = address + r;
2505 int32_t sum = (int32_t) augend + addend;
2506
2507 sim_debug (DBG_TRACEEXT|DBG_CAC, & cpu_dev,
2508 "awd augend 0%o addend 0%o sum 0%o\r\n",
2509 augend, addend, sum);
2510
2511 cpu.AR[ARn].WORDNO = (word18) sum & AMASK;
2512 SET_AR_CHAR_BITNO (ARn, 0, 0);
2513 #if defined(TESTING)
2514 HDBGRegARW (ARn, "awd");
2515 #endif
2516 }
2517
2518 void sbd (cpu_state_t * cpup)
2519 {
2520 uint ARn = GET_ARN (cpu.cu.IWB);
2521
2522 word18 address = SIGNEXT15_18 (GET_OFFSET (cpu.cu.IWB));
2523 word4 reg = (word4) GET_TD (cpu.cu.IWB);
2524
2525 word24 r = getCrAR (cpup, (word4) reg) & MASK24;
2526 if (GET_AR_BITNO (ARn) > 8)
2527 SET_AR_CHAR_BITNO (ARn, GET_AR_CHAR (ARn), 8);
2528
2529 if (GET_A (cpu.cu.IWB))
2530 {
2531 word24 bits = 9u * GET_AR_CHAR (ARn) + GET_AR_BITNO (ARn) - r;
2532 cpu.AR[ARn].WORDNO = (cpu.AR[ARn].WORDNO -
2533 address + bits / 36) & MASK18;
2534 if (r % 36)
2535 {
2536 SET_AR_CHAR_BITNO (ARn, (- ((bits % 36) / 9)) & MASK2,
2537 (- (bits % 9)) & MASK4);
2538 }
2539 }
2540 else
2541 {
2542 cpu.AR[ARn].WORDNO = (- (address + r / 36)) & MASK18;
2543 if (r % 36)
2544 {
2545 SET_AR_CHAR_BITNO (ARn, (- ((r % 36) / 9)) & MASK2,
2546 (- (r % 9)) & MASK4);
2547 }
2548 }
2549 #if defined(TESTING)
2550 HDBGRegARW (ARn, "sbd");
2551 #endif
2552 }
2553
2554 void swd (cpu_state_t * cpup)
2555 {
2556 uint ARn = GET_ARN (cpu.cu.IWB);
2557 CPTUR (cptUsePRn + ARn);
2558 int32_t address = SIGNEXT15_32 (GET_OFFSET (cpu.cu.IWB));
2559
2560
2561 word4 reg = (word4) GET_TD (cpu.cu.IWB);
2562
2563
2564 int32_t r = (int32_t) (getCrAR (cpup, reg) & MASK18);
2565 r = SIGNEXT18_32 ((word18) r);
2566
2567 sim_debug (DBG_TRACEEXT|DBG_CAC, & cpu_dev,
2568 "swd ARn 0%o address 0%o reg 0%o r 0%o\r\n",
2569 ARn, address, reg, r);
2570
2571 uint minued = 0;
2572 if (GET_A (cpu.cu.IWB))
2573 {
2574 sim_debug (DBG_TRACEEXT|DBG_CAC, & cpu_dev,
2575 "swd ARn %d WORDNO %o CHAR %o BITNO %0o %d.\r\n",
2576 ARn, cpu.PAR[ARn].WORDNO, GET_AR_CHAR (ARn),
2577 GET_AR_BITNO (ARn), GET_AR_BITNO (ARn));
2578
2579
2580 minued = cpu.AR [ARn].WORDNO;
2581 }
2582
2583 sim_debug (DBG_TRACEEXT|DBG_CAC, & cpu_dev,
2584 "swd minued 0%o\r\n", minued);
2585
2586 int32_t subtractend = address + r;
2587 int32_t difference = (int32_t) minued - subtractend;
2588
2589 sim_debug (DBG_TRACEEXT|DBG_CAC, & cpu_dev,
2590 "swd minued 0%o subtractend 0%o difference 0%o\r\n",
2591 minued, subtractend, difference);
2592
2593 cpu.AR [ARn].WORDNO = (word18) difference & AMASK;
2594 SET_AR_CHAR_BITNO (ARn, 0, 0);
2595 #if defined(TESTING)
2596 HDBGRegARW (ARn, "swd");
2597 #endif
2598 }
2599
2600 void s9bd (cpu_state_t * cpup)
2601 {
2602 uint ARn = GET_ARN (cpu.cu.IWB);
2603 CPTUR (cptUsePRn + ARn);
2604 word18 address = SIGNEXT15_18 (GET_OFFSET (cpu.cu.IWB));
2605
2606
2607 word4 reg = (word4) GET_TD (cpu.cu.IWB);
2608
2609
2610 word21 r = getCrAR (cpup, reg) & MASK21;;
2611
2612 sim_debug (DBG_TRACEEXT|DBG_CAC, & cpu_dev, "s9bd r 0%o\r\n", r);
2613
2614 sim_debug (DBG_TRACEEXT|DBG_CAC, & cpu_dev, "s9bd ARn 0%o address 0%o reg 0%o r 0%o\r\n", ARn, address, reg, r);
2615
2616 if (GET_A (cpu.cu.IWB))
2617 {
2618
2619
2620
2621 cpu.AR[ARn].WORDNO = (cpu.AR[ARn].WORDNO -
2622 address +
2623 (GET_AR_CHAR (ARn) - r) / 4) & MASK18;
2624
2625
2626
2627
2628 SET_AR_CHAR_BITNO (ARn, (GET_AR_CHAR (ARn) - r) & MASK2, 0);
2629
2630 }
2631 else
2632 {
2633 cpu.AR[ARn].WORDNO = (- (address + (r + 3) / 4)) & MASK18;
2634
2635
2636
2637 SET_AR_CHAR_BITNO (ARn, (-r) & MASK2, 0);
2638
2639 }
2640
2641 #if defined(TESTING)
2642 HDBGRegARW (ARn, "s9bd");
2643 #endif
2644
2645
2646
2647
2648 }
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677 void asxbd (cpu_state_t * cpup, uint sz, bool sub)
2678 {
2679
2680 uint map4 [64] =
2681 {
2682 0,
2683 0,
2684 0,
2685 0,
2686 0,
2687 5,
2688 5,
2689 5,
2690 5,
2691 5,
2692 5,
2693 5,
2694 5,
2695 5,
2696 5,
2697 5,
2698 9,
2699 9,
2700 9,
2701 9,
2702 9,
2703 14,
2704 14,
2705 14,
2706 14,
2707 14,
2708 14,
2709 14,
2710 14,
2711 14,
2712 14,
2713 14,
2714 18,
2715 18,
2716 18,
2717 18,
2718 18,
2719 23,
2720 23,
2721 23,
2722 23,
2723 23,
2724 23,
2725 23,
2726 23,
2727 23,
2728 23,
2729 23,
2730 27,
2731 27,
2732 27,
2733 27,
2734 27,
2735 32,
2736 32,
2737 32,
2738 32,
2739 32,
2740 32,
2741 32,
2742 32,
2743 32,
2744 32,
2745 32
2746 };
2747
2748 uint map6 [64] =
2749 {
2750 0,
2751 1,
2752 2,
2753 3,
2754 4,
2755 5,
2756 6,
2757 7,
2758 8,
2759 6,
2760 6,
2761 6,
2762 6,
2763 6,
2764 6,
2765 6,
2766 9,
2767 10,
2768 11,
2769 12,
2770 13,
2771 14,
2772 15,
2773 16,
2774 17,
2775 12,
2776 12,
2777 12,
2778 12,
2779 12,
2780 12,
2781 12,
2782 18,
2783 19,
2784 20,
2785 21,
2786 22,
2787 23,
2788 24,
2789 25,
2790 26,
2791 24,
2792 24,
2793 24,
2794 24,
2795 24,
2796 24,
2797 24,
2798 27,
2799 28,
2800 29,
2801 30,
2802 31,
2803 32,
2804 33,
2805 34,
2806 35,
2807 30,
2808 30,
2809 30,
2810 30,
2811 30,
2812 30,
2813 30
2814 };
2815
2816 uint map9 [64] =
2817 {
2818 0,
2819 1,
2820 2,
2821 3,
2822 4,
2823 5,
2824 6,
2825 7,
2826 8,
2827 8,
2828 8,
2829 8,
2830 8,
2831 8,
2832 8,
2833 8,
2834 9,
2835 10,
2836 11,
2837 12,
2838 13,
2839 14,
2840 15,
2841 16,
2842 17,
2843 17,
2844 17,
2845 17,
2846 17,
2847 17,
2848 17,
2849 17,
2850 18,
2851 19,
2852 20,
2853 21,
2854 22,
2855 23,
2856 24,
2857 25,
2858 26,
2859 26,
2860 26,
2861 26,
2862 26,
2863 26,
2864 26,
2865 26,
2866 27,
2867 28,
2868 29,
2869 30,
2870 31,
2871 32,
2872 33,
2873 34,
2874 35,
2875 35,
2876 35,
2877 35,
2878 35,
2879 35,
2880 35,
2881 35
2882 };
2883
2884
2885
2886
2887
2888 uint ARn = GET_ARN (cpu.cu.IWB);
2889 uint address = SIGNEXT15_18 (GET_OFFSET (cpu.cu.IWB));
2890 word4 reg = (word4) GET_TD (cpu.cu.IWB);
2891
2892
2893
2894
2895
2896
2897
2898 word36 rcnt = getCrAR (cpup, reg);
2899
2900 sim_debug (DBG_TRACEEXT|DBG_CAC, & cpu_dev, "asxbd sz %d r 0%"PRIo64"\r\n", sz, rcnt);
2901
2902
2903 uint r = 0;
2904
2905 if (sz == 1)
2906 r = (uint) (rcnt & MASK24);
2907 else if (sz == 4)
2908 r = (uint) (rcnt & MASK22);
2909 else if (sz == 6)
2910 r = (uint) (rcnt & MASK21);
2911 else if (sz == 9)
2912 r = (uint) (rcnt & MASK21);
2913 else
2914 r = (uint) (rcnt & MASK18);
2915
2916 sim_debug (DBG_TRACEEXT|DBG_CAC, & cpu_dev, "asxbd sz %d ARn 0%o address 0%o reg 0%o r 0%o\r\n", sz, ARn, address, reg, r);
2917
2918
2919
2920
2921
2922
2923 uint augend = 0;
2924 if (GET_A (cpu.cu.IWB))
2925 {
2926
2927 if (sz == 36)
2928 {
2929 augend = cpu.AR[ARn].WORDNO * 36u;
2930 }
2931 else
2932 {
2933 uint bitno = GET_AR_BITNO (ARn);
2934 uint charno = GET_AR_CHAR (ARn);
2935
2936
2937
2938
2939
2940 uint * map;
2941 if (sz == 4)
2942 map = map4;
2943 else if (sz == 6)
2944 map = map6;
2945 else
2946 map = map9;
2947
2948 augend = cpu.AR[ARn].WORDNO * 36u + map [charno * 16 + bitno];
2949 augend = augend % nxbits;
2950 }
2951 }
2952
2953
2954
2955
2956
2957 uint addend = 0;
2958 if (sz == 4)
2959 {
2960
2961
2962 addend = address * 36u + (r * 9) / 2;
2963
2964
2965
2966 if ((! sub) && r % 2)
2967 addend ++;
2968 }
2969 else
2970 addend = address * 36u + r * sz;
2971
2972
2973 addend = addend % nxbits;
2974
2975
2976
2977
2978
2979 uint sum = 0;
2980 if (sub)
2981 {
2982
2983 if (addend > augend)
2984 augend += nxbits;
2985 sum = augend - addend;
2986 }
2987 else
2988 {
2989 sum = augend + addend;
2990 sum %= nxbits;
2991 }
2992
2993 sim_debug (DBG_TRACEEXT|DBG_CAC, & cpu_dev, "asxbd augend 0%o addend 0%o sum 0%o\r\n", augend, addend, sum);
2994
2995
2996
2997
2998
2999 if (sz == 6 || sz == 9)
3000 {
3001 sum = (sum / sz) * sz;
3002 }
3003
3004
3005
3006
3007
3008 cpu.AR [ARn].WORDNO = (word18) (sum / 36u) & AMASK;
3009
3010
3011
3012 if (sz == 36)
3013 {
3014 SET_AR_CHAR_BITNO (ARn, 0, 0);
3015 }
3016 else
3017 {
3018 if (sz == 4)
3019 {
3020 static uint tab [36] [2] =
3021 {
3022
3023 { 0, 0 },
3024 { 0, 0 },
3025 { 0, 0 },
3026 { 0, 0 },
3027 { 0, 0 },
3028
3029 { 0, 5 },
3030 { 0, 5 },
3031 { 0, 5 },
3032 { 0, 5 },
3033
3034 { 1, 0 },
3035 { 1, 0 },
3036 { 1, 0 },
3037 { 1, 0 },
3038 { 1, 0 },
3039
3040 { 1, 5 },
3041 { 1, 5 },
3042 { 1, 5 },
3043 { 1, 5 },
3044
3045 { 2, 0 },
3046 { 2, 0 },
3047 { 2, 0 },
3048 { 2, 0 },
3049 { 2, 0 },
3050
3051 { 2, 5 },
3052 { 2, 5 },
3053 { 2, 5 },
3054 { 2, 5 },
3055
3056 { 3, 0 },
3057 { 3, 0 },
3058 { 3, 0 },
3059 { 3, 0 },
3060 { 3, 0 },
3061
3062 { 3, 5 },
3063 { 3, 5 },
3064 { 3, 5 },
3065 { 3, 5 }
3066 };
3067 uint charno = tab [sum % 36u] [0];
3068 uint bitno = tab [sum % 36u] [1];
3069 SET_AR_CHAR_BITNO (ARn, (word2) charno, (word4) bitno);
3070 }
3071 else
3072 {
3073 uint charno = (sum % 36u) / 9;
3074 uint bitno = sum % 9;
3075 SET_AR_CHAR_BITNO (ARn, (word2) charno, (word4) bitno);
3076 }
3077 }
3078 #if defined(TESTING)
3079 HDBGRegARW (ARn, "asxbd");
3080 #endif
3081 }
3082
3083 void cmpc (cpu_state_t * cpup)
3084 {
3085 EISstruct * e = & cpu.currentEISinstruction;
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111 fault_ipr_subtype_ mod_fault = 0;
3112
3113 #if !defined(EIS_SETUP)
3114 setupOperandDescriptor (cpup, 1, &mod_fault);
3115 setupOperandDescriptor (cpup, 2, &mod_fault);
3116 #endif
3117 parseAlphanumericOperandDescriptor (cpup, 1, 1, false, &mod_fault);
3118 parseAlphanumericOperandDescriptor (cpup, 2, 1, false, &mod_fault);
3119
3120 L68_ (
3121
3122 if (mod_fault)
3123 {
3124 doFault (FAULT_IPR,
3125 (_fault_subtype) {.fault_ipr_subtype=mod_fault},
3126 "Illegal modifier");
3127 }
3128 )
3129
3130
3131 if (IWB_IRODD & 0000600000000)
3132 doFault (FAULT_IPR, (_fault_subtype) {.fault_ipr_subtype=FR_ILL_OP|mod_fault}, "cmpc 9-10 MBZ");
3133
3134
3135 if (!(e->MF[0] & MFkID) && e -> op [0] & 0000000010000)
3136 doFault (FAULT_IPR, (_fault_subtype) {.fault_ipr_subtype=FR_ILL_PROC|mod_fault}, "cmpc op1 23 MBZ");
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150 DPS8M_ (
3151
3152 if (mod_fault)
3153 {
3154 doFault (FAULT_IPR,
3155 (_fault_subtype) {.fault_ipr_subtype=mod_fault},
3156 "Illegal modifier");
3157 }
3158 )
3159
3160 word9 fill = getbits36_9 (cpu.cu.IWB, 0);
3161
3162 SET_I_ZERO;
3163 SET_I_CARRY;
3164
3165 PNL (L68_ (if (max (e->N1, e->N2) < 128)
3166 DU_CYCLE_FLEN_128;))
3167
3168 for (; cpu.du.CHTALLY < min (e->N1, e->N2); cpu.du.CHTALLY ++)
3169 {
3170 tandd_eis_sample (cpup, cpu.du.CHTALLY, TDPER (e -> TA1));
3171 word9 c1 = EISget469 (cpup, 1, cpu.du.CHTALLY);
3172 word9 c2 = EISget469 (cpup, 2, cpu.du.CHTALLY);
3173 sim_debug (DBG_TRACEEXT, & cpu_dev, "cmpc tally %d c1 %03o c2 %03o\r\n", cpu.du.CHTALLY, c1, c2);
3174 if (c1 != c2)
3175 {
3176 CLR_I_ZERO;
3177 SC_I_CARRY (c1 > c2);
3178 cleanupOperandDescriptor (cpup, 1);
3179 cleanupOperandDescriptor (cpup, 2);
3180 return;
3181 }
3182 }
3183
3184 if (e -> N1 < e -> N2)
3185 {
3186 for( ; cpu.du.CHTALLY < e->N2; cpu.du.CHTALLY ++)
3187 {
3188 tandd_eis_sample (cpup, cpu.du.CHTALLY, TDPER (e -> TA1));
3189 word9 c1 = fill;
3190 word9 c2 = EISget469 (cpup, 2, cpu.du.CHTALLY);
3191
3192 if (c1 != c2)
3193 {
3194 CLR_I_ZERO;
3195 SC_I_CARRY (c1 > c2);
3196 cleanupOperandDescriptor (cpup, 1);
3197 cleanupOperandDescriptor (cpup, 2);
3198 return;
3199 }
3200 }
3201 }
3202 else if (e->N1 > e->N2)
3203 {
3204 for ( ; cpu.du.CHTALLY < e->N1; cpu.du.CHTALLY ++)
3205 {
3206 tandd_eis_sample (cpup, cpu.du.CHTALLY, TDPER (e -> TA1));
3207 word9 c1 = EISget469 (cpup, 1, cpu.du.CHTALLY);
3208 word9 c2 = fill;
3209
3210 if (c1 != c2)
3211 {
3212 CLR_I_ZERO;
3213 SC_I_CARRY (c1 > c2);
3214 cleanupOperandDescriptor (cpup, 1);
3215 cleanupOperandDescriptor (cpup, 2);
3216 return;
3217 }
3218 }
3219 }
3220
3221 cleanupOperandDescriptor (cpup, 1);
3222 cleanupOperandDescriptor (cpup, 2);
3223 }
3224
3225
3226
3227
3228
3229 void scd (cpu_state_t * cpup)
3230 {
3231 EISstruct * e = & cpu.currentEISinstruction;
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249 fault_ipr_subtype_ mod_fault = 0;
3250
3251 #if !defined(EIS_SETUP)
3252 setupOperandDescriptor (cpup, 1, &mod_fault);
3253 setupOperandDescriptor (cpup, 2, &mod_fault);
3254 setupOperandDescriptorCache (cpup,3);
3255 #endif
3256
3257 parseAlphanumericOperandDescriptor (cpup, 1, 1, false, &mod_fault);
3258 parseAlphanumericOperandDescriptor (cpup, 2, 1, true, &mod_fault);
3259 parseArgOperandDescriptor (cpup, 3, &mod_fault);
3260
3261 L68_ (
3262
3263 if (mod_fault)
3264 {
3265 doFault (FAULT_IPR,
3266 (_fault_subtype) {.fault_ipr_subtype=mod_fault},
3267 "Illegal modifier");
3268 }
3269 )
3270
3271
3272 if (IWB_IRODD & 0777600000000)
3273 {
3274
3275 doFault (FAULT_IPR, (_fault_subtype) {.fault_ipr_subtype=FR_ILL_OP|mod_fault}, "scd 0-10 MBZ");
3276 }
3277
3278
3279 if (!(e->MF[0] & MFkID) && e -> op [0] & 0000000010000)
3280 doFault (FAULT_IPR, (_fault_subtype) {.fault_ipr_subtype=FR_ILL_PROC|mod_fault}, "scd op1 23 MBZ");
3281
3282
3283 if (!(e->MF[2] & MFkID) && e -> op [2] & 0000000777660)
3284 doFault (FAULT_IPR, (_fault_subtype) {.fault_ipr_subtype=FR_ILL_PROC|mod_fault}, "scd op3 18-28. 30-31 MBZ");
3285
3286 DPS8M_ (
3287
3288 if (mod_fault)
3289 {
3290 doFault (FAULT_IPR,
3291 (_fault_subtype) {.fault_ipr_subtype=mod_fault},
3292 "Illegal modifier");
3293 }
3294 )
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306 word9 c1 = 0;
3307 word9 c2 = 0;
3308
3309 if (! (e -> MF2 & MFkID) && ((e -> MF2 & MFkREGMASK) == 3))
3310 {
3311
3312 #if defined(EIS_PTR3)
3313 switch (TA1)
3314 #else
3315 switch (e -> TA1)
3316 #endif
3317 {
3318 case CTA4:
3319 #if defined(EIS_PTR)
3320 c1 = (cpu.du.D2_PTR_W >> 13) & 017;
3321 c2 = (cpu.du.D2_PTR_W >> 9) & 017;
3322 #else
3323 c1 = (e -> ADDR2.address >> 13) & 017;
3324 c2 = (e -> ADDR2.address >> 9) & 017;
3325 #endif
3326 break;
3327
3328 case CTA6:
3329 #if defined(EIS_PTR)
3330 c1 = (cpu.du.D2_PTR_W >> 12) & 077;
3331 c2 = (cpu.du.D2_PTR_W >> 6) & 077;
3332 #else
3333 c1 = (e -> ADDR2.address >> 12) & 077;
3334 c2 = (e -> ADDR2.address >> 6) & 077;
3335 #endif
3336 break;
3337
3338 case CTA9:
3339 #if defined(EIS_PTR)
3340 c1 = (cpu.du.D2_PTR_W >> 9) & 0777;
3341 c2 = (cpu.du.D2_PTR_W ) & 0777;
3342 #else
3343 c1 = (e -> ADDR2.address >> 9) & 0777;
3344 c2 = (e -> ADDR2.address ) & 0777;
3345 #endif
3346 break;
3347 }
3348 }
3349 else
3350 {
3351 c1 = EISget469 (cpup, 2, 0);
3352 c2 = EISget469 (cpup, 2, 1);
3353 }
3354
3355 #if defined(EIS_PTR3)
3356 switch (TA1)
3357 #else
3358 switch (e -> TA1)
3359 #endif
3360 {
3361 case CTA4:
3362 c1 &= 017;
3363 c2 &= 017;
3364 break;
3365
3366 case CTA6:
3367 c1 &= 077;
3368 c2 &= 077;
3369 break;
3370
3371 case CTA9:
3372 c1 &= 0777;
3373 c2 &= 0777;
3374 break;
3375 }
3376
3377 PNL (L68_ (if (e->N1 < 128)
3378 DU_CYCLE_FLEN_128;))
3379
3380 word9 yCharn11;
3381 word9 yCharn12;
3382 if (e -> N1)
3383 {
3384 uint limit = e -> N1 - 1;
3385 for ( ; cpu.du.CHTALLY < limit; cpu.du.CHTALLY ++)
3386 {
3387 tandd_eis_sample (cpup, cpu.du.CHTALLY, 3);
3388 yCharn11 = EISget469 (cpup, 1, cpu.du.CHTALLY);
3389 yCharn12 = EISget469 (cpup, 1, cpu.du.CHTALLY + 1);
3390 if (yCharn11 == c1 && yCharn12 == c2)
3391 break;
3392 }
3393 SC_I_TALLY (cpu.du.CHTALLY == limit);
3394 }
3395 else
3396 {
3397 SET_I_TALLY;
3398 }
3399
3400
3401 word36 CY3 = setbits36_24 (0, 12, cpu.du.CHTALLY);
3402 EISWriteIdx (cpup, & e -> ADDR3, 0, CY3, true);
3403
3404 cleanupOperandDescriptor (cpup, 1);
3405 cleanupOperandDescriptor (cpup, 2);
3406 cleanupOperandDescriptor (cpup, 3);
3407 }
3408
3409
3410
3411
3412
3413 void scdr (cpu_state_t * cpup)
3414 {
3415 EISstruct * e = & cpu.currentEISinstruction;
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433 fault_ipr_subtype_ mod_fault = 0;
3434
3435 #if !defined(EIS_SETUP)
3436 setupOperandDescriptor(cpup, 1, &mod_fault);
3437 setupOperandDescriptor(cpup, 2, &mod_fault);
3438 setupOperandDescriptorCache(cpup,3);
3439 #endif
3440
3441 parseAlphanumericOperandDescriptor(cpup, 1, 1, false, &mod_fault);
3442 parseAlphanumericOperandDescriptor(cpup, 2, 1, true, &mod_fault);
3443 parseArgOperandDescriptor (cpup, 3, &mod_fault);
3444
3445 L68_ (
3446
3447 if (mod_fault)
3448 {
3449 doFault (FAULT_IPR,
3450 (_fault_subtype) {.fault_ipr_subtype=mod_fault},
3451 "Illegal modifier");
3452 }
3453 )
3454
3455
3456 if (IWB_IRODD & 0777600000000)
3457 {
3458
3459 doFault (FAULT_IPR, (_fault_subtype) {.fault_ipr_subtype=FR_ILL_OP|mod_fault}, "scdr 0-10 MBZ");
3460 }
3461
3462
3463 if (!(e->MF[0] & MFkID) && e -> op [0] & 0000000010000)
3464 doFault (FAULT_IPR, (_fault_subtype) {.fault_ipr_subtype=FR_ILL_PROC|mod_fault}, "scdr op1 23 MBZ");
3465
3466
3467 if (!(e->MF[2] & MFkID) && e -> op [2] & 0000000777660)
3468 doFault (FAULT_IPR, (_fault_subtype) {.fault_ipr_subtype=FR_ILL_PROC|mod_fault}, "scdr op3 18-28. 30-31 MBZ");
3469
3470 DPS8M_ (
3471
3472 if (mod_fault)
3473 {
3474 doFault (FAULT_IPR,
3475 (_fault_subtype) {.fault_ipr_subtype=mod_fault},
3476 "Illegal modifier");
3477 }
3478 )
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490 word9 c1 = 0;
3491 word9 c2 = 0;
3492
3493 if (! (e -> MF2 & MFkID) && ((e -> MF2 & MFkREGMASK) == 3))
3494 {
3495
3496 #if defined(EIS_PTR3)
3497 switch (TA1)
3498 #else
3499 switch (e -> TA1)
3500 #endif
3501 {
3502 case CTA4:
3503 #if defined(EIS_PTR)
3504 c1 = (cpu.du.D2_PTR_W >> 13) & 017;
3505 c2 = (cpu.du.D2_PTR_W >> 9) & 017;
3506 #else
3507 c1 = (e -> ADDR2.address >> 13) & 017;
3508 c2 = (e -> ADDR2.address >> 9) & 017;
3509 #endif
3510 break;
3511
3512 case CTA6:
3513 #if defined(EIS_PTR)
3514 c1 = (cpu.du.D2_PTR_W >> 12) & 077;
3515 c2 = (cpu.du.D2_PTR_W >> 6) & 077;
3516 #else
3517 c1 = (e -> ADDR2.address >> 12) & 077;
3518 c2 = (e -> ADDR2.address >> 6) & 077;
3519 #endif
3520 break;
3521
3522 case CTA9:
3523 #if defined(EIS_PTR)
3524 c1 = (cpu.du.D2_PTR_W >> 9) & 0777;
3525 c2 = (cpu.du.D2_PTR_W ) & 0777;
3526 #else
3527 c1 = (e -> ADDR2.address >> 9) & 0777;
3528 c2 = (e -> ADDR2.address ) & 0777;
3529 #endif
3530 break;
3531 }
3532 }
3533 else
3534 {
3535 c1 = EISget469 (cpup, 2, 0);
3536 c2 = EISget469 (cpup, 2, 1);
3537 }
3538
3539 #if defined(EIS_PTR3)
3540 switch (TA1)
3541 #else
3542 switch (e -> TA1)
3543 #endif
3544 {
3545 case CTA4:
3546 c1 &= 017;
3547 c2 &= 017;
3548 break;
3549
3550 case CTA6:
3551 c1 &= 077;
3552 c2 &= 077;
3553 break;
3554
3555 case CTA9:
3556 c1 &= 0777;
3557 c2 &= 0777;
3558 break;
3559 }
3560
3561 word9 yCharn11;
3562 word9 yCharn12;
3563
3564 PNL (L68_ (if (e->N1 < 128)
3565 DU_CYCLE_FLEN_128;))
3566
3567 if (e -> N1)
3568 {
3569 uint limit = e -> N1 - 1;
3570
3571 for ( ; cpu.du.CHTALLY < limit; cpu.du.CHTALLY ++)
3572 {
3573 tandd_eis_sample (cpup, cpu.du.CHTALLY, 3);
3574 yCharn11 = EISget469 (cpup, 1, limit - cpu.du.CHTALLY - 1);
3575 yCharn12 = EISget469 (cpup, 1, limit - cpu.du.CHTALLY);
3576
3577 if (yCharn11 == c1 && yCharn12 == c2)
3578 break;
3579 }
3580 SC_I_TALLY (cpu.du.CHTALLY == limit);
3581 }
3582 else
3583 {
3584 SET_I_TALLY;
3585 }
3586
3587
3588 word36 CY3 = setbits36_24 (0, 12, cpu.du.CHTALLY);
3589 EISWriteIdx (cpup, & e -> ADDR3, 0, CY3, true);
3590
3591 cleanupOperandDescriptor (cpup, 1);
3592 cleanupOperandDescriptor (cpup, 2);
3593 cleanupOperandDescriptor (cpup, 3);
3594 }
3595
3596
3597
3598
3599
3600 void scm (cpu_state_t * cpup)
3601 {
3602 EISstruct * e = & cpu.currentEISinstruction;
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636 fault_ipr_subtype_ mod_fault = 0;
3637
3638 #if !defined(EIS_SETUP)
3639 setupOperandDescriptor (cpup, 1, &mod_fault);
3640 setupOperandDescriptor (cpup, 2, &mod_fault);
3641 setupOperandDescriptorCache (cpup,3);
3642 #endif
3643
3644 parseAlphanumericOperandDescriptor (cpup, 1, 1, false, &mod_fault);
3645 parseAlphanumericOperandDescriptor (cpup, 2, 1, true, &mod_fault);
3646 parseArgOperandDescriptor (cpup, 3, &mod_fault);
3647
3648 L68_ (
3649
3650 if (mod_fault)
3651 {
3652 doFault (FAULT_IPR,
3653 (_fault_subtype) {.fault_ipr_subtype=mod_fault},
3654 "Illegal modifier");
3655 }
3656 )
3657
3658
3659 if (IWB_IRODD & 0000600000000)
3660 doFault (FAULT_IPR, (_fault_subtype) {.fault_ipr_subtype=FR_ILL_OP|mod_fault}, "scm 9-10 MBZ");
3661
3662
3663 if (!(e->MF[0] & MFkID) && e -> op [0] & 0000000010000)
3664 doFault (FAULT_IPR, (_fault_subtype) {.fault_ipr_subtype=FR_ILL_PROC|mod_fault}, "scm op1 23 MBZ");
3665
3666
3667 if (!(e->MF[2] & MFkID) && e -> op [2] & 0000000777660)
3668 doFault (FAULT_IPR, (_fault_subtype) {.fault_ipr_subtype=FR_ILL_PROC|mod_fault}, "scm op3 18-28, 39-31 MBZ");
3669
3670 DPS8M_ (
3671
3672 if (mod_fault)
3673 {
3674 doFault (FAULT_IPR,
3675 (_fault_subtype) {.fault_ipr_subtype=mod_fault},
3676 "Illegal modifier");
3677 }
3678 )
3679
3680
3681
3682
3683
3684
3685 uint mask = (uint) getbits36_9 (cpu.cu.IWB, 0);
3686
3687
3688
3689
3690
3691
3692
3693 word9 ctest = 0;
3694 if (! (e -> MF2 & MFkID) && ((e -> MF2 & MFkREGMASK) == 3))
3695 {
3696 word18 duo = GETHI (e -> OP2);
3697
3698 #if defined(EIS_PTR3)
3699 switch (TA1)
3700 #else
3701 switch (e -> TA1)
3702 #endif
3703 {
3704 case CTA4:
3705 ctest = (duo >> 13) & 017;
3706 break;
3707 case CTA6:
3708 ctest = (duo >> 12) & 077;
3709 break;
3710 case CTA9:
3711 ctest = (duo >> 9) & 0777;
3712 break;
3713 }
3714 }
3715 else
3716 {
3717 ctest = EISget469 (cpup, 2, 0);
3718 }
3719
3720 #if defined(EIS_PTR3)
3721 switch (TA1)
3722 #else
3723 switch (e -> TA1)
3724 #endif
3725 {
3726 case CTA4:
3727 ctest &= 017;
3728 break;
3729 case CTA6:
3730 ctest &= 077;
3731 break;
3732 case CTA9:
3733 ctest &= 0777;
3734 }
3735
3736 PNL (L68_ (if (e->N1 < 128)
3737 DU_CYCLE_FLEN_128;))
3738
3739 uint limit = e -> N1;
3740
3741 for ( ; cpu.du.CHTALLY < limit; cpu.du.CHTALLY ++)
3742 {
3743 tandd_eis_sample (cpup, cpu.du.CHTALLY, 3);
3744 word9 yCharn1 = EISget469 (cpup, 1, cpu.du.CHTALLY);
3745 word9 c = ((~mask) & (yCharn1 ^ ctest)) & 0777;
3746 if (c == 0)
3747 {
3748
3749
3750
3751 break;
3752 }
3753 }
3754
3755 word36 CY3 = setbits36_24 (0, 12, cpu.du.CHTALLY);
3756
3757 SC_I_TALLY (cpu.du.CHTALLY == limit);
3758
3759 EISWriteIdx (cpup, & e -> ADDR3, 0, CY3, true);
3760
3761 cleanupOperandDescriptor (cpup, 1);
3762 cleanupOperandDescriptor (cpup, 2);
3763 cleanupOperandDescriptor (cpup, 3);
3764 }
3765
3766
3767
3768
3769 void scmr (cpu_state_t * cpup)
3770 {
3771 EISstruct * e = & cpu.currentEISinstruction;
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805 fault_ipr_subtype_ mod_fault = 0;
3806
3807 #if !defined(EIS_SETUP)
3808 setupOperandDescriptor (cpup, 1, &mod_fault);
3809 setupOperandDescriptor (cpup, 2, &mod_fault);
3810 setupOperandDescriptorCache (cpup,3);
3811 #endif
3812
3813 parseAlphanumericOperandDescriptor (cpup, 1, 1, false, &mod_fault);
3814 parseAlphanumericOperandDescriptor (cpup, 2, 1, true, &mod_fault);
3815 parseArgOperandDescriptor (cpup, 3, &mod_fault);
3816
3817 L68_ (
3818
3819 if (mod_fault)
3820 {
3821 doFault (FAULT_IPR,
3822 (_fault_subtype) {.fault_ipr_subtype=mod_fault},
3823 "Illegal modifier");
3824 }
3825 )
3826
3827
3828 if (IWB_IRODD & 0000600000000)
3829 doFault (FAULT_IPR, (_fault_subtype) {.fault_ipr_subtype=FR_ILL_OP|mod_fault}, "scmr 9-10 MBZ");
3830
3831
3832 if (!(e->MF[0] & MFkID) && e -> op [0] & 0000000010000)
3833 doFault (FAULT_IPR, (_fault_subtype) {.fault_ipr_subtype=FR_ILL_PROC|mod_fault}, "scmr op1 23 MBZ");
3834
3835
3836
3837
3838
3839
3840 if (!(e->MF[2] & MFkID) && e -> op [2] & 0000000777660)
3841 doFault (FAULT_IPR, (_fault_subtype) {.fault_ipr_subtype=FR_ILL_PROC|mod_fault}, "scmr op3 18-28, 39-31 MBZ");
3842
3843 DPS8M_ (
3844
3845 if (mod_fault)
3846 {
3847 doFault (FAULT_IPR,
3848 (_fault_subtype) {.fault_ipr_subtype=mod_fault},
3849 "Illegal modifier");
3850 }
3851 )
3852
3853
3854
3855
3856
3857
3858 uint mask = (uint) getbits36_9 (cpu.cu.IWB, 0);
3859
3860
3861
3862
3863
3864
3865
3866 word9 ctest = 0;
3867 if (! (e -> MF2 & MFkID) && ((e -> MF2 & MFkREGMASK) == 3))
3868 {
3869 word18 duo = GETHI (e -> OP2);
3870
3871 #if defined(EIS_PTR3)
3872 switch (TA1)
3873 #else
3874 switch (e -> TA1)
3875 #endif
3876 {
3877 case CTA4:
3878 ctest = (duo >> 13) & 017;
3879 break;
3880 case CTA6:
3881 ctest = (duo >> 12) & 077;
3882 break;
3883 case CTA9:
3884 ctest = (duo >> 9) & 0777;
3885 break;
3886 }
3887 }
3888 else
3889 {
3890 ctest = EISget469 (cpup, 2, 0);
3891 }
3892
3893 #if defined(EIS_PTR3)
3894 switch (TA1)
3895 #else
3896 switch (e -> TA1)
3897 #endif
3898 {
3899 case CTA4:
3900 ctest &= 017;
3901 break;
3902 case CTA6:
3903 ctest &= 077;
3904 break;
3905 case CTA9:
3906 ctest &= 0777;
3907 }
3908
3909 PNL (L68_ (if (e->N1 < 128)
3910 DU_CYCLE_FLEN_128;))
3911
3912 uint limit = e -> N1;
3913 for ( ; cpu.du.CHTALLY < limit; cpu.du.CHTALLY ++)
3914 {
3915 tandd_eis_sample (cpup, cpu.du.CHTALLY, 3);
3916 word9 yCharn1 = EISget469 (cpup, 1, limit - cpu.du.CHTALLY - 1);
3917 word9 c = ((~mask) & (yCharn1 ^ ctest)) & 0777;
3918 if (c == 0)
3919 {
3920
3921
3922
3923 break;
3924 }
3925 }
3926
3927 word36 CY3 = setbits36_24 (0, 12, cpu.du.CHTALLY);
3928
3929 SC_I_TALLY (cpu.du.CHTALLY == limit);
3930
3931 EISWriteIdx (cpup, & e -> ADDR3, 0, CY3, true);
3932
3933 cleanupOperandDescriptor (cpup, 1);
3934 cleanupOperandDescriptor (cpup, 2);
3935 cleanupOperandDescriptor (cpup, 3);
3936 }
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963 static word9 xlate (cpu_state_t * cpup, EISaddr * xlatTbl, uint dstTA, uint c)
3964 {
3965 uint idx = (c / 4) & 0177;
3966 word36 entry = EISReadIdx(cpup, xlatTbl, idx);
3967
3968 uint pos9 = c % 4;
3969 word9 cout = GETBYTE (entry, pos9);
3970 switch (dstTA)
3971 {
3972 case CTA4:
3973 return cout & 017;
3974 case CTA6:
3975 return cout & 077;
3976 case CTA9:
3977 return cout;
3978 }
3979 return 0;
3980 }
3981
3982 void tct (cpu_state_t * cpup)
3983 {
3984 EISstruct * e = & cpu.currentEISinstruction;
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007 fault_ipr_subtype_ mod_fault = 0;
4008
4009 #if !defined(EIS_SETUP)
4010 setupOperandDescriptor (cpup, 1, &mod_fault);
4011 setupOperandDescriptorCache (cpup,2);
4012 setupOperandDescriptorCache (cpup,3);
4013 #endif
4014
4015 parseAlphanumericOperandDescriptor (cpup, 1, 1, false, &mod_fault);
4016 parseArgOperandDescriptor (cpup, 2, &mod_fault);
4017 parseArgOperandDescriptor (cpup, 3, &mod_fault);
4018
4019 L68_ (
4020
4021 if (mod_fault)
4022 {
4023 doFault (FAULT_IPR,
4024 (_fault_subtype) {.fault_ipr_subtype=mod_fault},
4025 "Illegal modifier");
4026 }
4027 )
4028
4029
4030 if (IWB_IRODD & 0777777000000)
4031 doFault (FAULT_IPR, (_fault_subtype) {.fault_ipr_subtype=FR_ILL_OP|mod_fault}, "tct 0-17 MBZ");
4032
4033
4034 if (!(e->MF[0] & MFkID) && e -> op [0] & 0000000010000)
4035 doFault (FAULT_IPR, (_fault_subtype) {.fault_ipr_subtype=FR_ILL_PROC|mod_fault}, "tct op1 23 MBZ");
4036
4037
4038 if (!(e->MF[1] & MFkID) && e -> op [1] & 0000000777660)
4039 doFault (FAULT_IPR, (_fault_subtype) {.fault_ipr_subtype=FR_ILL_PROC|mod_fault}, "tct op2 18-28, 39-31 MBZ");
4040
4041
4042 if (!(e->MF[2] & MFkID) && e -> op [2] & 0000000777660)
4043 doFault (FAULT_IPR, (_fault_subtype) {.fault_ipr_subtype=FR_ILL_PROC|mod_fault}, "tct op3 18-28, 39-31 MBZ");
4044
4045 DPS8M_ (
4046
4047 if (mod_fault)
4048 {
4049 doFault (FAULT_IPR,
4050 (_fault_subtype) {.fault_ipr_subtype=mod_fault},
4051 "Illegal modifier");
4052 }
4053 )
4054
4055 #if defined(EIS_PTR3)
4056 sim_debug (DBG_TRACEEXT, & cpu_dev,
4057 "TCT CN1: %d TA1: %d\r\n", e -> CN1, TA1);
4058 #else
4059 sim_debug (DBG_TRACEEXT, & cpu_dev,
4060 "TCT CN1: %d TA1: %d\r\n", e -> CN1, e -> TA1);
4061 #endif
4062
4063 uint srcSZ = 0;
4064
4065 #if defined(EIS_PTR3)
4066 switch (TA1)
4067 #else
4068 switch (e -> TA1)
4069 #endif
4070 {
4071 case CTA4:
4072 srcSZ = 4;
4073 break;
4074 case CTA6:
4075 srcSZ = 6;
4076 break;
4077 case CTA9:
4078 srcSZ = 9;
4079 break;
4080 }
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121 word36 CY3 = 0;
4122
4123 sim_debug (DBG_TRACEEXT, & cpu_dev,
4124 "TCT N1 %d\r\n", e -> N1);
4125
4126 PNL (L68_ (if (e->N1 < 128)
4127 DU_CYCLE_FLEN_128;))
4128
4129 for ( ; cpu.du.CHTALLY < e -> N1; cpu.du.CHTALLY ++)
4130 {
4131 tandd_eis_sample (cpup, cpu.du.CHTALLY, 2);
4132 word9 c = EISget469 (cpup, 1, cpu.du.CHTALLY);
4133
4134 uint m = 0;
4135
4136 switch (srcSZ)
4137 {
4138 case 4:
4139 m = c & 017;
4140 break;
4141 case 6:
4142 m = c & 077;
4143 break;
4144 case 9:
4145 m = c;
4146 break;
4147 }
4148
4149 word9 cout = xlate (cpup, &e->ADDR2, CTA9, m);
4150
4151 sim_debug (DBG_TRACEEXT, & cpu_dev,
4152 "TCT c %03o %c cout %03o %c\r\n",
4153 m, isprint ((int) m) ? '?' : (char) m,
4154 cout, isprint ((int) cout) ? '?' : (char) cout);
4155
4156 if (cout)
4157 {
4158
4159 CY3 = setbits36_9 (0, 0, cout);
4160 break;
4161 }
4162 }
4163
4164 SC_I_TALLY (cpu.du.CHTALLY == e -> N1);
4165
4166
4167 putbits36_24 (& CY3, 12, cpu.du.CHTALLY);
4168 EISWriteIdx (cpup, & e -> ADDR3, 0, CY3, true);
4169
4170 cleanupOperandDescriptor (cpup, 1);
4171 cleanupOperandDescriptor (cpup, 2);
4172 cleanupOperandDescriptor (cpup, 3);
4173 }
4174
4175 void tctr (cpu_state_t * cpup)
4176 {
4177 EISstruct * e = & cpu.currentEISinstruction;
4178
4179
4180
4181
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197
4198
4199
4200
4201
4202
4203 fault_ipr_subtype_ mod_fault = 0;
4204
4205 #if !defined(EIS_SETUP)
4206 setupOperandDescriptor (cpup, 1, &mod_fault);
4207 setupOperandDescriptorCache (cpup,2);
4208 setupOperandDescriptorCache (cpup,3);
4209 #endif
4210
4211 parseAlphanumericOperandDescriptor (cpup, 1, 1, false, &mod_fault);
4212 parseArgOperandDescriptor (cpup, 2, &mod_fault);
4213 parseArgOperandDescriptor (cpup, 3, &mod_fault);
4214
4215 L68_ (
4216
4217 if (mod_fault)
4218 {
4219 doFault (FAULT_IPR,
4220 (_fault_subtype) {.fault_ipr_subtype=mod_fault},
4221 "Illegal modifier");
4222 }
4223 )
4224
4225
4226 if (IWB_IRODD & 0777777000000)
4227 doFault (FAULT_IPR, (_fault_subtype) {.fault_ipr_subtype=FR_ILL_OP|mod_fault}, "tctr 0-17 MBZ");
4228
4229
4230 if (!(e->MF[0] & MFkID) && e -> op [0] & 0000000010000)
4231 doFault (FAULT_IPR, (_fault_subtype) {.fault_ipr_subtype=FR_ILL_PROC|mod_fault}, "tctr op1 23 MBZ");
4232
4233
4234 if (!(e->MF[1] & MFkID) && e -> op [1] & 0000000777660)
4235 doFault (FAULT_IPR, (_fault_subtype) {.fault_ipr_subtype=FR_ILL_PROC|mod_fault}, "tctr op2 18-28, 39-31 MBZ");
4236
4237
4238 if (!(e->MF[2] & MFkID) && e -> op [2] & 0000000777660)
4239 doFault (FAULT_IPR, (_fault_subtype) {.fault_ipr_subtype=FR_ILL_PROC|mod_fault}, "tctr op3 18-28, 39-31 MBZ");
4240
4241 DPS8M_ (
4242
4243 if (mod_fault)
4244 {
4245 doFault (FAULT_IPR,
4246 (_fault_subtype) {.fault_ipr_subtype=mod_fault},
4247 "Illegal modifier");
4248 }
4249 )
4250
4251 #if defined(EIS_PTR3)
4252 sim_debug (DBG_TRACEEXT, & cpu_dev,
4253 "TCTR CN1: %d TA1: %d\r\n", e -> CN1, TA1);
4254 #else
4255 sim_debug (DBG_TRACEEXT, & cpu_dev,
4256 "TCTR CN1: %d TA1: %d\r\n", e -> CN1, e -> TA1);
4257 #endif
4258
4259 uint srcSZ = 0;
4260
4261 #if defined(EIS_PTR3)
4262 switch (TA1)
4263 #else
4264 switch (e -> TA1)
4265 #endif
4266 {
4267 case CTA4:
4268 srcSZ = 4;
4269 break;
4270 case CTA6:
4271 srcSZ = 6;
4272 break;
4273 case CTA9:
4274 srcSZ = 9;
4275 break;
4276 }
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
4300
4301
4302
4303
4304
4305
4306
4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317 word36 CY3 = 0;
4318
4319 sim_debug (DBG_TRACEEXT, & cpu_dev,
4320 "TCT N1 %d\r\n", e -> N1);
4321
4322 PNL (L68_ (if (e->N1 < 128)
4323 DU_CYCLE_FLEN_128;))
4324
4325 uint limit = e -> N1;
4326 for ( ; cpu.du.CHTALLY < limit; cpu.du.CHTALLY ++)
4327 {
4328 tandd_eis_sample (cpup, cpu.du.CHTALLY, 2);
4329 word9 c = EISget469 (cpup, 1, limit - cpu.du.CHTALLY - 1);
4330
4331 uint m = 0;
4332
4333 switch (srcSZ)
4334 {
4335 case 4:
4336 m = c & 017;
4337 break;
4338 case 6:
4339 m = c & 077;
4340 break;
4341 case 9:
4342 m = c;
4343 break;
4344 }
4345
4346 word9 cout = xlate (cpup, &e->ADDR2, CTA9, m);
4347
4348 sim_debug (DBG_TRACEEXT, & cpu_dev,
4349 "TCT c %03o %c cout %03o %c\r\n",
4350 m, isprint ((int) m) ? '?' : (char) m,
4351 cout, isprint ((int) cout) ? '?' : (char) cout);
4352
4353 if (cout)
4354 {
4355
4356 CY3 = setbits36_9 (0, 0, cout);
4357 break;
4358 }
4359 }
4360
4361 SC_I_TALLY (cpu.du.CHTALLY == e -> N1);
4362
4363
4364 putbits36_24 (& CY3, 12, cpu.du.CHTALLY);
4365 EISWriteIdx (cpup, & e -> ADDR3, 0, CY3, true);
4366
4367 cleanupOperandDescriptor (cpup, 1);
4368 cleanupOperandDescriptor (cpup, 2);
4369 cleanupOperandDescriptor (cpup, 3);
4370 }
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408 static bool isGBCDOvp (uint c, bool * isNeg)
4409 {
4410 if (c & 020)
4411 {
4412 * isNeg = false;
4413 return true;
4414 }
4415 if (c & 040)
4416 {
4417 * isNeg = true;
4418 return true;
4419 }
4420 return false;
4421 }
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434 void mlr (cpu_state_t * cpup)
4435 {
4436 EISstruct * e = & cpu.currentEISinstruction;
4437
4438
4439
4440
4441
4442
4443
4444 fault_ipr_subtype_ mod_fault = 0;
4445
4446 #if !defined(EIS_SETUP)
4447 setupOperandDescriptor (cpup, 1, &mod_fault);
4448 setupOperandDescriptor (cpup, 2, &mod_fault);
4449
4450 #endif
4451
4452 parseAlphanumericOperandDescriptor(cpup, 1, 1, false, &mod_fault);
4453 parseAlphanumericOperandDescriptor(cpup, 2, 2, false, &mod_fault);
4454
4455 L68_ (
4456
4457 if (mod_fault)
4458 {
4459 doFault (FAULT_IPR,
4460 (_fault_subtype) {.fault_ipr_subtype=mod_fault},
4461 "Illegal modifier");
4462 }
4463 )
4464
4465
4466 if (IWB_IRODD & 0000200000000)
4467 doFault (FAULT_IPR, (_fault_subtype) {.fault_ipr_subtype=FR_ILL_OP|mod_fault}, "mlr 10 MBZ");
4468
4469
4470 if (!(e->MF[0] & MFkID) && e -> op [0] & 0000000010000)
4471 doFault (FAULT_IPR, (_fault_subtype) {.fault_ipr_subtype=FR_ILL_PROC|mod_fault}, "mlr op1 23 MBZ");
4472
4473
4474 if (!(e->MF[1] & MFkID) && e -> op [1] & 0000000010000)
4475 doFault (FAULT_IPR, (_fault_subtype) {.fault_ipr_subtype=FR_ILL_PROC|mod_fault}, "mlr op2 23 MBZ");
4476
4477 DPS8M_ (
4478
4479 if (mod_fault)
4480 {
4481 doFault (FAULT_IPR,
4482 (_fault_subtype) {.fault_ipr_subtype=mod_fault},
4483 "Illegal modifier");
4484 }
4485 )
4486
4487 int srcSZ = 0, dstSZ = 0;
4488
4489 #if defined(EIS_PTR3)
4490 switch (TA1)
4491 #else
4492 switch (e -> TA1)
4493 #endif
4494 {
4495 case CTA4:
4496 srcSZ = 4;
4497 break;
4498 case CTA6:
4499 srcSZ = 6;
4500 break;
4501 case CTA9:
4502 srcSZ = 9;
4503 break;
4504 }
4505
4506 #if defined(EIS_PTR3)
4507 switch (TA2)
4508 #else
4509 switch (e -> TA2)
4510 #endif
4511 {
4512 case CTA4:
4513 dstSZ = 4;
4514 break;
4515 case CTA6:
4516 dstSZ = 6;
4517 break;
4518 case CTA9:
4519 dstSZ = 9;
4520 break;
4521 }
4522
4523 word1 T = getbits36_1 (cpu.cu.IWB, 9);
4524
4525 word9 fill = getbits36_9 (cpu.cu.IWB, 0);
4526 word9 fillT = fill;
4527
4528
4529 switch (dstSZ)
4530 {
4531 case 4:
4532 fillT = fill & 017;
4533 break;
4534 case 6:
4535 fillT = fill & 077;
4536 break;
4537 }
4538
4539
4540
4541
4542
4543
4544
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554
4555
4556
4557
4558
4559
4560
4561 PNL (L68_ (if (max (e->N1, e->N2) < 128)
4562 DU_CYCLE_FLEN_128;))
4563
4564 #if defined(EIS_PTR3)
4565 bool ovp = (e -> N1 < e -> N2) && (fill & 0400) && (TA1 == 1) &&
4566 (TA2 == 2);
4567 #else
4568 bool ovp = (e -> N1 < e -> N2) && (fill & 0400) && (e -> TA1 == 1) &&
4569 (e -> TA2 == 2);
4570 #endif
4571
4572 bool isNeg = false;
4573
4574
4575
4576 #if defined(EIS_PTR3)
4577 sim_debug (DBG_TRACEEXT, & cpu_dev,
4578 "MLR TALLY %u TA1 %u TA2 %u N1 %u N2 %u CN1 %u CN2 %u\r\n",
4579 cpu.du.CHTALLY, TA1, TA2, e -> N1, e -> N2, e -> CN1, e -> CN2);
4580 #else
4581 sim_debug (DBG_TRACEEXT, & cpu_dev,
4582 "MLR TALLY %u TA1 %u TA2 %u N1 %u N2 %u CN1 %u CN2 %u\r\n",
4583 cpu.du.CHTALLY, e -> TA1, e -> TA2, e -> N1, e -> N2, e -> CN1, e -> CN2);
4584 #endif
4585
4586
4587
4588
4589
4590
4591
4592
4593
4594
4595
4596
4597
4598 if ((cpu.du.CHTALLY % PGSZ) == 0 &&
4599 #if defined(EIS_PTR3)
4600 TA1 == CTA9 &&
4601 TA2 == CTA9 &&
4602 #else
4603 e -> TA1 == CTA9 &&
4604 e -> TA2 == CTA9 &&
4605 #endif
4606 (e -> N1 % (PGSZ * 4)) == 0 &&
4607 e -> N2 == e -> N1 &&
4608 e -> CN1 == 0 &&
4609 e -> CN2 == 0 &&
4610 #if defined(EIS_PTR)
4611 (cpu.du.D1_PTR_W & PGMK) == 0 &&
4612 (cpu.du.D2_PTR_W & PGMK) == 0)
4613 #else
4614 (e -> ADDR1.address & PGMK) == 0 &&
4615 (e -> ADDR2.address & PGMK) == 0)
4616 #endif
4617 {
4618 sim_debug (DBG_TRACEEXT, & cpu_dev, "MLR special case #3\r\n");
4619 while (cpu.du.CHTALLY < e -> N1)
4620 {
4621 word36 pg [PGSZ];
4622 EISReadPage (cpup, & e -> ADDR1, cpu.du.CHTALLY / 4, pg);
4623 EISWritePage (cpup, & e -> ADDR2, cpu.du.CHTALLY / 4, pg);
4624 cpu.du.CHTALLY += PGSZ * 4;
4625 }
4626 cleanupOperandDescriptor (cpup, 1);
4627 cleanupOperandDescriptor (cpup, 2);
4628
4629
4630 CLR_I_TRUNC;
4631 return;
4632 }
4633
4634
4635
4636
4637
4638 if ((cpu.du.CHTALLY % PGSZ) == 0 &&
4639 #if defined(EIS_PTR3)
4640 TA1 == CTA9 &&
4641 TA2 == CTA9 &&
4642 #else
4643 e -> TA1 == CTA9 &&
4644 e -> TA2 == CTA9 &&
4645 #endif
4646 e -> N1 == 0 &&
4647 (e -> N2 % (PGSZ * 4)) == 0 &&
4648 e -> CN1 == 0 &&
4649 e -> CN2 == 0 &&
4650 #if defined(EIS_PTR)
4651 (cpu.du.D1_PTR_W & PGMK) == 0 &&
4652 (cpu.du.D2_PTR_W& PGMK) == 0)
4653 #else
4654 (e -> ADDR1.address & PGMK) == 0 &&
4655 (e -> ADDR2.address & PGMK) == 0)
4656 #endif
4657 {
4658 sim_debug (DBG_TRACEEXT, & cpu_dev, "MLR special case #4\r\n");
4659 word36 pg [PGSZ];
4660 if (fill)
4661 {
4662 word36 w = (word36) fill | ((word36) fill << 9) | ((word36) fill << 18) | ((word36) fill << 27);
4663 for (uint i = 0; i < PGSZ; i ++)
4664 pg [i] = w;
4665 }
4666 else
4667 {
4668 (void)memset (pg, 0, sizeof (pg));
4669 }
4670 while (cpu.du.CHTALLY < e -> N2)
4671 {
4672 EISWritePage (cpup, & e -> ADDR2, cpu.du.CHTALLY / 4, pg);
4673 cpu.du.CHTALLY += PGSZ * 4;
4674 }
4675 cleanupOperandDescriptor (cpup, 1);
4676 cleanupOperandDescriptor (cpup, 2);
4677
4678
4679 CLR_I_TRUNC;
4680 return;
4681 }
4682
4683
4684
4685
4686 #if defined(EIS_PTR3)
4687 if (TA1 == CTA9 &&
4688 TA2 == CTA9 &&
4689 #else
4690 if (e -> TA1 == CTA9 &&
4691 e -> TA2 == CTA9 &&
4692 #endif
4693 e -> N1 % 4 == 0 &&
4694 e -> N2 == e -> N1 &&
4695 e -> CN1 == 0 &&
4696 e -> CN2 == 0)
4697 {
4698 sim_debug (DBG_TRACEEXT, & cpu_dev, "MLR special case #1\r\n");
4699 for ( ; cpu.du.CHTALLY < e -> N2; cpu.du.CHTALLY += 4)
4700 {
4701 tandd_eis_sample (cpup, cpu.du.CHTALLY, 4);
4702 uint n = cpu.du.CHTALLY / 4;
4703 word36 w = EISReadIdx (cpup, & e -> ADDR1, n);
4704 EISWriteIdx (cpup, & e -> ADDR2, n, w, true);
4705 }
4706 cleanupOperandDescriptor (cpup, 1);
4707 cleanupOperandDescriptor (cpup, 2);
4708
4709
4710 CLR_I_TRUNC;
4711 return;
4712 }
4713
4714
4715
4716
4717 #if defined(EIS_PTR3)
4718 if (TA1 == CTA9 &&
4719 TA2 == CTA9 &&
4720 #else
4721 if (e -> TA1 == CTA9 &&
4722 e -> TA2 == CTA9 &&
4723 #endif
4724 e -> N1 == 0 &&
4725 e -> N2 % 4 == 0 &&
4726 e -> CN1 == 0 &&
4727 e -> CN2 == 0)
4728 {
4729 sim_debug (DBG_TRACEEXT, & cpu_dev, "MLR special case #2\r\n");
4730 word36 w = (word36) fill | ((word36) fill << 9) | ((word36) fill << 18) | ((word36) fill << 27);
4731 for ( ; cpu.du.CHTALLY < e -> N2; cpu.du.CHTALLY += 4)
4732 {
4733 tandd_eis_sample (cpup, cpu.du.CHTALLY, 4);
4734 uint n = cpu.du.CHTALLY / 4;
4735 EISWriteIdx (cpup, & e -> ADDR2, n, w, true);
4736 }
4737 cleanupOperandDescriptor (cpup, 1);
4738 cleanupOperandDescriptor (cpup, 2);
4739
4740
4741 CLR_I_TRUNC;
4742 return;
4743 }
4744
4745 uint tdPer = TDPER (e -> TA2);
4746 for ( ; cpu.du.CHTALLY < min (e->N1, e->N2); cpu.du.CHTALLY ++)
4747 {
4748 tandd_eis_sample (cpup, cpu.du.CHTALLY, tdPer);
4749 word9 c = EISget469 (cpup, 1, cpu.du.CHTALLY);
4750 word9 cout = 0;
4751
4752 #if defined(EIS_PTR3)
4753 if (TA1 == TA2)
4754 #else
4755 if (e -> TA1 == e -> TA2)
4756 #endif
4757 EISput469 (cpup, 2, cpu.du.CHTALLY, c);
4758 else
4759 {
4760
4761
4762
4763 cout = c;
4764 switch (srcSZ)
4765 {
4766 case 6:
4767 switch(dstSZ)
4768 {
4769 case 4:
4770 cout = c & 017;
4771 break;
4772 case 9:
4773 break;
4774 }
4775 break;
4776 case 9:
4777 switch(dstSZ)
4778 {
4779 case 4:
4780 cout = c & 017;
4781 break;
4782 case 6:
4783 cout = c & 077;
4784 break;
4785 }
4786 break;
4787 }
4788
4789
4790
4791
4792
4793
4794
4795 if (ovp && (cpu.du.CHTALLY == e -> N1 - 1))
4796 {
4797
4798
4799 isGBCDOvp (c, & isNeg);
4800 }
4801 EISput469 (cpup, 2, cpu.du.CHTALLY, cout);
4802 }
4803 }
4804
4805
4806
4807
4808
4809
4810
4811 if (e -> N1 < e -> N2)
4812 {
4813 for ( ; cpu.du.CHTALLY < e -> N2 ; cpu.du.CHTALLY ++)
4814 {
4815 tandd_eis_sample (cpup, cpu.du.CHTALLY, tdPer);
4816
4817 if (ovp && (cpu.du.CHTALLY == e -> N2 - 1))
4818 {
4819 if (isNeg)
4820 EISput469 (cpup, 2, cpu.du.CHTALLY, 015);
4821 else
4822 EISput469 (cpup, 2, cpu.du.CHTALLY, 014);
4823 }
4824 else
4825 EISput469 (cpup, 2, cpu.du.CHTALLY, fillT);
4826 }
4827 }
4828 cleanupOperandDescriptor (cpup, 1);
4829 cleanupOperandDescriptor (cpup, 2);
4830
4831 if (e -> N1 > e -> N2)
4832 {
4833 SET_I_TRUNC;
4834 if (T && ! TST_I_OMASK)
4835 doFault (FAULT_OFL, fst_zero, "mlr truncation fault");
4836 }
4837 else
4838 CLR_I_TRUNC;
4839 }
4840
4841 void mrl (cpu_state_t * cpup)
4842 {
4843 EISstruct * e = & cpu.currentEISinstruction;
4844
4845
4846
4847
4848
4849
4850
4851 fault_ipr_subtype_ mod_fault = 0;
4852
4853 #if !defined(EIS_SETUP)
4854 setupOperandDescriptor (cpup, 1, &mod_fault);
4855 setupOperandDescriptor (cpup, 2, &mod_fault);
4856
4857 #endif
4858
4859 parseAlphanumericOperandDescriptor(cpup, 1, 1, false, &mod_fault);
4860 parseAlphanumericOperandDescriptor(cpup, 2, 2, false, &mod_fault);
4861
4862 L68_ (
4863
4864 if (mod_fault)
4865 {
4866 doFault (FAULT_IPR,
4867 (_fault_subtype) {.fault_ipr_subtype=mod_fault},
4868 "Illegal modifier");
4869 }
4870 )
4871
4872
4873 if (IWB_IRODD & 0000200000000)
4874 doFault (FAULT_IPR, (_fault_subtype) {.fault_ipr_subtype=FR_ILL_OP|mod_fault}, "mrl 10 MBZ");
4875
4876
4877 if (!(e->MF[0] & MFkID) && e -> op [0] & 0000000010000)
4878 doFault (FAULT_IPR, (_fault_subtype) {.fault_ipr_subtype=FR_ILL_PROC|mod_fault}, "mrl op1 23 MBZ");
4879
4880
4881 if (!(e->MF[1] & MFkID) && e -> op [1] & 0000000010000)
4882 doFault (FAULT_IPR, (_fault_subtype) {.fault_ipr_subtype=FR_ILL_PROC|mod_fault}, "mrl op2 23 MBZ");
4883
4884 DPS8M_ (
4885
4886 if (mod_fault)
4887 {
4888 doFault (FAULT_IPR,
4889 (_fault_subtype) {.fault_ipr_subtype=mod_fault},
4890 "Illegal modifier");
4891 }
4892 )
4893
4894 int srcSZ = 0, dstSZ = 0;
4895
4896 #if defined(EIS_PTR3)
4897 switch (TA1)
4898 #else
4899 switch (e -> TA1)
4900 #endif
4901 {
4902 case CTA4:
4903 srcSZ = 4;
4904 break;
4905 case CTA6:
4906 srcSZ = 6;
4907 break;
4908 case CTA9:
4909 srcSZ = 9;
4910 break;
4911 }
4912
4913 #if defined(EIS_PTR3)
4914 switch (TA2)
4915 #else
4916 switch (e -> TA2)
4917 #endif
4918 {
4919 case CTA4:
4920 dstSZ = 4;
4921 break;
4922 case CTA6:
4923 dstSZ = 6;
4924 break;
4925 case CTA9:
4926 dstSZ = 9;
4927 break;
4928 }
4929
4930 word1 T = getbits36_1 (cpu.cu.IWB, 9);
4931
4932 word9 fill = getbits36_9 (cpu.cu.IWB, 0);
4933 word9 fillT = fill;
4934
4935
4936 switch (dstSZ)
4937 {
4938 case 4:
4939 fillT = fill & 017;
4940 break;
4941 case 6:
4942 fillT = fill & 077;
4943 break;
4944 }
4945
4946
4947
4948
4949
4950
4951
4952
4953
4954
4955
4956
4957
4958
4959
4960
4961
4962
4963
4964
4965
4966
4967
4968 #if defined(EIS_PTR3)
4969 bool ovp = (e -> N1 < e -> N2) && (fill & 0400) && (TA1 == 1) &&
4970 (TA2 == 2);
4971 #else
4972 bool ovp = (e -> N1 < e -> N2) && (fill & 0400) && (e -> TA1 == 1) &&
4973 (e -> TA2 == 2);
4974 #endif
4975 bool isNeg = false;
4976
4977
4978
4979 PNL (L68_ (if (max (e->N1, e->N2) < 128)
4980 DU_CYCLE_FLEN_128;))
4981
4982
4983
4984
4985
4986 #if defined(EIS_PTR3)
4987 if (TA1 == CTA9 &&
4988 TA2 == CTA9 &&
4989 #else
4990 if (e -> TA1 == CTA9 &&
4991 e -> TA2 == CTA9 &&
4992 #endif
4993 e -> N1 % 4 == 0 &&
4994 e -> N2 == e -> N1 &&
4995 e -> CN1 == 0 &&
4996 e -> CN2 == 0)
4997 {
4998 sim_debug (DBG_TRACEEXT, & cpu_dev, "MRL special case #1\r\n");
4999 uint limit = e -> N2;
5000 for ( ; cpu.du.CHTALLY < limit; cpu.du.CHTALLY += 4)
5001 {
5002 tandd_eis_sample (cpup, cpu.du.CHTALLY, TDPER (e -> TA2));
5003 uint n = (limit - cpu.du.CHTALLY - 1) / 4;
5004 word36 w = EISReadIdx (cpup, & e -> ADDR1, n);
5005 EISWriteIdx (cpup, & e -> ADDR2, n, w, true);
5006 }
5007 cleanupOperandDescriptor (cpup, 1);
5008 cleanupOperandDescriptor (cpup, 2);
5009
5010
5011 CLR_I_TRUNC;
5012 return;
5013 }
5014
5015
5016
5017
5018 #if defined(EIS_PTR3)
5019 if (TA1 == CTA9 &&
5020 TA2 == CTA9 &&
5021 #else
5022 if (e -> TA1 == CTA9 &&
5023 e -> TA2 == CTA9 &&
5024 #endif
5025 e -> N1 == 0 &&
5026 e -> N2 % 4 == 0 &&
5027 e -> CN1 == 0 &&
5028 e -> CN2 == 0)
5029 {
5030 sim_debug (DBG_TRACEEXT, & cpu_dev, "MRL special case #2\r\n");
5031 word36 w = (word36) fill |
5032 ((word36) fill << 9) |
5033 ((word36) fill << 18) |
5034 ((word36) fill << 27);
5035 uint limit = e -> N2;
5036 for ( ; cpu.du.CHTALLY < e -> N2; cpu.du.CHTALLY += 4)
5037 {
5038 tandd_eis_sample (cpup, cpu.du.CHTALLY, TDPER (e -> TA2));
5039 uint n = (limit - cpu.du.CHTALLY - 1) / 4;
5040 EISWriteIdx (cpup, & e -> ADDR2, n, w, true);
5041 }
5042 cleanupOperandDescriptor (cpup, 1);
5043 cleanupOperandDescriptor (cpup, 2);
5044
5045
5046 CLR_I_TRUNC;
5047 return;
5048 }
5049
5050 for ( ; cpu.du.CHTALLY < min (e -> N1, e -> N2); cpu.du.CHTALLY ++)
5051 {
5052 tandd_eis_sample (cpup, cpu.du.CHTALLY, TDPER (e -> TA2));
5053 word9 c = EISget469 (cpup, 1, e -> N1 - cpu.du.CHTALLY - 1);
5054 word9 cout = 0;
5055
5056 #if defined(EIS_PTR3)
5057 if (TA1 == TA2)
5058 #else
5059 if (e -> TA1 == e -> TA2)
5060 #endif
5061 EISput469 (cpup, 2, e -> N2 - cpu.du.CHTALLY - 1, c);
5062 else
5063 {
5064
5065
5066
5067 cout = c;
5068 switch (srcSZ)
5069 {
5070 case 6:
5071 switch(dstSZ)
5072 {
5073 case 4:
5074 cout = c & 017;
5075 break;
5076 case 9:
5077 break;
5078 }
5079 break;
5080 case 9:
5081 switch(dstSZ)
5082 {
5083 case 4:
5084 cout = c & 017;
5085 break;
5086 case 6:
5087 cout = c & 077;
5088 break;
5089 }
5090 break;
5091 }
5092
5093
5094
5095
5096
5097
5098
5099
5100 if (ovp && (cpu.du.CHTALLY == 0))
5101 {
5102
5103 isGBCDOvp (c, & isNeg);
5104 }
5105 EISput469 (cpup, 2, e -> N2 - cpu.du.CHTALLY - 1, cout);
5106 }
5107 }
5108
5109
5110
5111
5112
5113
5114
5115 if (e -> N1 < e -> N2)
5116 {
5117 for ( ; cpu.du.CHTALLY < e -> N2 ; cpu.du.CHTALLY ++)
5118 {
5119 tandd_eis_sample (cpup, cpu.du.CHTALLY, TDPER (e -> TA2));
5120
5121 if (ovp && (cpu.du.CHTALLY == e -> N2 - 1))
5122 {
5123 if (isNeg)
5124 EISput469 (cpup, 2, e -> N2 - cpu.du.CHTALLY - 1, 015);
5125 else
5126 EISput469 (cpup, 2, e -> N2 - cpu.du.CHTALLY - 1, 014);
5127 }
5128 else
5129 {
5130 EISput469 (cpup, 2, e -> N2 - cpu.du.CHTALLY - 1, fillT);
5131 }
5132 }
5133 }
5134 cleanupOperandDescriptor (cpup, 1);
5135 cleanupOperandDescriptor (cpup, 2);
5136
5137 if (e -> N1 > e -> N2)
5138 {
5139 SET_I_TRUNC;
5140 if (T && ! TST_I_OMASK)
5141 doFault (FAULT_OFL, fst_zero, "mrl truncation fault");
5142 }
5143 else
5144 CLR_I_TRUNC;
5145 }
5146
5147
5148
5149
5150
5151
5152
5153
5154
5155
5156
5157
5158
5159
5160
5161
5162 #define isDecimalZero(c) ((e->srcTA == CTA9) ? \
5163 ((c) == '0') : \
5164 (((c) & 017) == 0))
5165
5166
5167
5168
5169
5170
5171
5172
5173 static void EISloadInputBufferNumeric (cpu_state_t * cpup, int k)
5174 {
5175 EISstruct * e = & cpu.currentEISinstruction;
5176
5177 word9 *p = e->inBuffer;
5178 (void)memset(e->inBuffer, 0, sizeof(e->inBuffer));
5179
5180 int pos = (int) e->CN[k-1];
5181
5182 int TN = (int) e->TN[k-1];
5183 int S = (int) e->S[k-1];
5184
5185
5186 int N = (int) e->N[k-1];
5187
5188 EISaddr *a = &e->addr[k-1];
5189
5190 e->sign = 1;
5191 e->exponent = 0;
5192
5193 for(int n = 0 ; n < N ; n += 1)
5194 {
5195 word9 c = EISget49(cpup, a, &pos, TN);
5196 sim_debug (DBG_TRACEEXT, & cpu_dev, "src: %d: %o\r\n", n, c);
5197
5198
5199
5200
5201
5202
5203
5204
5205
5206 switch(S)
5207 {
5208 case CSFL:
5209
5210
5211
5212
5213
5214
5215
5216
5217
5218
5219
5220
5221
5222
5223
5224
5225
5226 if (n == 0)
5227 {
5228 c &= 0xf;
5229
5230 if (c < 012 || c > 017)
5231 doFault (FAULT_IPR,
5232 fst_ill_dig,
5233 "loadInputBufferNumeric(1): illegal char in "
5234 "input");
5235
5236 if (c == 015)
5237 e->sign = -1;
5238
5239 e->srcTally -= 1;
5240 }
5241 else if (TN == CTN9 && n == N-1)
5242 {
5243 e->exponent = (signed char)(c & 0377);
5244 e->srcTally -= 1;
5245 }
5246 else if (TN == CTN4 && n == N-2)
5247 {
5248 e->exponent = (c & 0xf);
5249 e->exponent <<= 4;
5250 e->srcTally -= 1;
5251 }
5252 else if (TN == CTN4 && n == N-1)
5253 {
5254 e->exponent |= (c & 0xf);
5255
5256 signed char ce = (signed char) (e->exponent & 0xff);
5257 e->exponent = ce;
5258
5259 e->srcTally -= 1;
5260 }
5261 else
5262 {
5263 c &= 0xf;
5264 if (c > 011)
5265 doFault(FAULT_IPR, fst_ill_dig, "loadInputBufferNumeric(2): illegal char in input");
5266
5267 *p++ = c;
5268 }
5269 break;
5270
5271 case CSLS:
5272
5273
5274
5275 c &= 0xf;
5276
5277 if (n == 0)
5278 {
5279 if (c < 012 || c > 017)
5280 doFault(FAULT_IPR, fst_ill_dig, "loadInputBufferNumeric(3): illegal char in input");
5281
5282 if (c == 015)
5283 e->sign = -1;
5284 e->srcTally -= 1;
5285 }
5286 else
5287 {
5288 if (c > 011)
5289 doFault(FAULT_IPR, fst_ill_dig, "loadInputBufferNumeric(4): illegal char in input");
5290 *p++ = c;
5291 }
5292 break;
5293
5294 case CSTS:
5295 c &= 0xf;
5296
5297 if (n == N-1)
5298 {
5299 if (c < 012 || c > 017)
5300 doFault(FAULT_IPR, fst_ill_dig, "loadInputBufferNumeric(5): illegal char in input");
5301 if (c == 015)
5302 e->sign = -1;
5303 e->srcTally -= 1;
5304 }
5305 else
5306 {
5307 if (c > 011)
5308 doFault(FAULT_IPR, fst_ill_dig, "loadInputBufferNumeric(6): illegal char in input");
5309 *p++ = c;
5310 }
5311 break;
5312
5313 case CSNS:
5314 c &= 0xf;
5315
5316 *p++ = c;
5317 break;
5318 }
5319 }
5320 if_sim_debug (DBG_TRACEEXT, & cpu_dev)
5321 {
5322 sim_debug (DBG_TRACEEXT, & cpu_dev, "inBuffer:");
5323 for (word9 *q = e->inBuffer; q < p; q ++)
5324 sim_debug (DBG_TRACEEXT, & cpu_dev, " %02o", * q);
5325 sim_debug (DBG_TRACEEXT, & cpu_dev, "\r\n");
5326 }
5327 }
5328
5329
5330
5331
5332
5333
5334
5335
5336 static void EISloadInputBufferAlphnumeric (cpu_state_t * cpup, int k)
5337 {
5338 EISstruct * e = & cpu.currentEISinstruction;
5339
5340 word9 * p = e -> inBuffer;
5341 (void)memset (e -> inBuffer, 0, sizeof (e -> inBuffer));
5342
5343
5344
5345
5346
5347
5348
5349 uint N = min (e-> N1, 63);
5350
5351 for (uint n = 0 ; n < N ; n ++)
5352 {
5353 word9 c = EISget469 (cpup, k, n);
5354 * p ++ = c;
5355 }
5356 }
5357
5358 static void EISwriteOutputBufferToMemory (cpu_state_t * cpup, int k)
5359 {
5360 EISstruct * e = & cpu.currentEISinstruction;
5361
5362 for (uint n = 0 ; n < (uint) e -> dstTally; n ++)
5363 {
5364 word9 c49 = e -> outBuffer [n];
5365 EISput469 (cpup, k, n, c49);
5366 }
5367 }
5368
5369 static void writeToOutputBuffer (cpu_state_t *cpup, word9 **dstAddr, int szSrc, int szDst, word9 c49)
5370 {
5371 EISstruct * e = & cpu.currentEISinstruction;
5372
5373
5374
5375
5376
5377
5378
5379
5380 if (e -> mvne)
5381 {
5382 switch (szSrc)
5383
5384 {
5385 case 4:
5386 switch (szDst)
5387 {
5388 case 4:
5389 ** dstAddr = c49 & 0xf;
5390 break;
5391 case 6:
5392 ** dstAddr = c49 & 077;
5393 break;
5394 case 9:
5395 ** dstAddr = c49 | (e -> editInsertionTable [7] & 0760);
5396 break;
5397 }
5398 break;
5399 case 6:
5400 switch (szDst)
5401 {
5402 case 4:
5403 ** dstAddr = c49 & 0xf;
5404 break;
5405 case 6:
5406 ** dstAddr = c49;
5407 break;
5408 case 9:
5409 ** dstAddr = c49;
5410 break;
5411 }
5412 break;
5413
5414
5415
5416 case 9:
5417 switch(szDst)
5418 {
5419 case 4:
5420 ** dstAddr = c49 & 0xf;
5421 break;
5422 case 6:
5423 ** dstAddr = c49 & 077;
5424 break;
5425 case 9:
5426 ** dstAddr = c49;
5427 break;
5428 }
5429 break;
5430 }
5431 }
5432 else
5433 {
5434 switch(szDst)
5435 {
5436 case 4:
5437 ** dstAddr = c49 & 0xf;
5438 break;
5439 case 6:
5440 ** dstAddr = c49 & 077;
5441 break;
5442 case 9:
5443 ** dstAddr = c49;
5444 break;
5445 }
5446 }
5447 e->dstTally -= 1;
5448 *dstAddr += 1;
5449 }
5450
5451
5452
5453
5454
5455 static char* defaultEditInsertionTable = " *+-$,.0";
5456
5457
5458
5459
5460
5461
5462
5463
5464
5465
5466
5467
5468
5469
5470
5471
5472
5473
5474
5475
5476
5477
5478
5479
5480
5481
5482
5483
5484
5485
5486
5487
5488 static int mopCHT (cpu_state_t * cpup)
5489 {
5490 EISstruct * e = & cpu.currentEISinstruction;
5491 (void)memset(&e->editInsertionTable, 0, sizeof(e->editInsertionTable));
5492 for(int i = 0 ; i < 8 ; i += 1)
5493 {
5494 if (e->mopTally == 0)
5495 {
5496 e->_faults |= FAULT_IPR;
5497 break;
5498 }
5499 #if defined(EIS_PTR2)
5500 word9 entry = EISget49(cpup, &e->ADDR2, &e->mopPos, CTN9);
5501 #else
5502 word9 entry = EISget49(cpup, e->mopAddress, &e->mopPos, CTN9);
5503 #endif
5504 e->editInsertionTable[i] = entry & 0777;
5505 e->mopTally -= 1;
5506 }
5507 return 0;
5508 }
5509
5510
5511
5512
5513
5514
5515
5516
5517
5518
5519
5520
5521
5522
5523
5524
5525
5526
5527
5528
5529
5530
5531
5532 static int mopENF (cpu_state_t * cpup)
5533 {
5534 EISstruct * e = & cpu.currentEISinstruction;
5535
5536 if (!(e->mopIF & 010))
5537 {
5538
5539 if (!e->mopES && !e->mopSN)
5540 {
5541 writeToOutputBuffer(cpup, &e->out, 9, e->dstSZ, e->editInsertionTable[2]);
5542 e->mopES = true;
5543 }
5544
5545 if (!e->mopES && e->mopSN)
5546 {
5547 writeToOutputBuffer(cpup, &e->out, 9, e->dstSZ, e->editInsertionTable[3]);
5548 e->mopES = true;
5549 }
5550
5551 } else {
5552 if (!e->mopES)
5553 {
5554
5555 writeToOutputBuffer(cpup, &e->out, 9, e->dstSZ, e->editInsertionTable[4]);
5556 e->mopES = true;
5557 }
5558
5559 }
5560
5561
5562 if (e->mopIF & 04)
5563 e->mopBZ = true;
5564
5565 return 0;
5566 }
5567
5568
5569
5570
5571
5572
5573
5574
5575
5576
5577
5578 static int mopIGN (cpu_state_t * cpup)
5579 {
5580 EISstruct * e = & cpu.currentEISinstruction;
5581
5582
5583 if (e->mopIF == 0)
5584 e->mopIF = 16;
5585
5586 for(int n = 0 ; n < e->mopIF ; n += 1)
5587 {
5588 if (e->dstTally == 0)
5589 break;
5590 if (e->srcTally == 0)
5591 {
5592
5593 e->_faults |= FAULT_IPR;
5594 break;
5595 }
5596
5597 e->srcTally -= 1;
5598 e->in += 1;
5599 }
5600 return 0;
5601 }
5602
5603
5604
5605
5606
5607
5608
5609
5610
5611
5612 static int mopINSA (cpu_state_t * cpup)
5613 {
5614 EISstruct * e = & cpu.currentEISinstruction;
5615
5616 if (e->mopIF >= 9 )
5617 {
5618 e->_faults |= FAULT_IPR;
5619 return 0;
5620 }
5621
5622
5623
5624
5625
5626
5627 if (!e->mopES)
5628 {
5629 writeToOutputBuffer(cpup, &e->out, 9, e->dstSZ, e->editInsertionTable[1]);
5630
5631 if (e->mopIF == 0)
5632 {
5633 if (e->mopTally == 0)
5634 {
5635 e->_faults |= FAULT_IPR;
5636 return 0;
5637 }
5638 # if defined(EIS_PTR2)
5639 EISget49(cpup, &e->ADDR2, &e->mopPos, CTN9);
5640 # else
5641 EISget49(cpup, e->mopAddress, &e->mopPos, CTN9);
5642 # endif
5643 e->mopTally -= 1;
5644 }
5645 }
5646
5647
5648
5649 else
5650 {
5651 if (e->mopIF == 0)
5652 {
5653 if (e->mopTally == 0)
5654 {
5655 e->_faults |= FAULT_IPR;
5656 return 0;
5657 }
5658 # if defined(EIS_PTR2)
5659 word9 c = EISget49(cpup, &e->ADDR2, &e->mopPos, CTN9);
5660 # else
5661 word9 c = EISget49(cpup, e->mopAddress, &e->mopPos, CTN9);
5662 # endif
5663 writeToOutputBuffer(cpup, &e->out, 9, e->dstSZ, c);
5664 e->mopTally -= 1;
5665 }
5666
5667
5668 else
5669 {
5670 writeToOutputBuffer(cpup, &e->out, 9, e->dstSZ, e->editInsertionTable[e->mopIF-1]);
5671 }
5672 }
5673
5674
5675
5676
5677
5678
5679
5680
5681
5682
5683
5684
5685
5686
5687
5688
5689
5690
5691
5692
5693
5694
5695
5696
5697
5698
5699
5700
5701
5702
5703
5704
5705
5706
5707
5708
5709
5710
5711
5712
5713
5714
5715
5716
5717
5718
5719
5720
5721
5722 return 0;
5723 }
5724
5725
5726
5727
5728
5729
5730
5731
5732
5733
5734
5735
5736
5737
5738
5739
5740
5741
5742
5743 static int mopINSB (cpu_state_t * cpup)
5744 {
5745 EISstruct * e = & cpu.currentEISinstruction;
5746
5747 if (e->mopIF >= 9 )
5748 {
5749 e->_faults |= FAULT_IPR;
5750 return 0;
5751 }
5752
5753 if (!e->mopES)
5754 {
5755
5756
5757
5758 writeToOutputBuffer(cpup, &e->out, 9, e->dstSZ, e->editInsertionTable[0]);
5759
5760 if (e->mopIF == 0)
5761 {
5762 if (e->mopTally == 0)
5763 {
5764 e->_faults |= FAULT_IPR;
5765 return 0;
5766 }
5767 #if defined(EIS_PTR2)
5768 EISget49(cpup, &e->ADDR2, &e->mopPos, CTN9);
5769 #else
5770 EISget49(cpup, e->mopAddress, &e->mopPos, CTN9);
5771 #endif
5772 e->mopTally -= 1;
5773 }
5774
5775 } else {
5776
5777
5778
5779 if (e->mopIF)
5780 {
5781
5782
5783
5784 writeToOutputBuffer(cpup, &e->out, 9, e->dstSZ, e->editInsertionTable[e->mopIF - 1]);
5785 } else {
5786
5787
5788
5789 if (e->mopTally == 0)
5790 {
5791 e->_faults |= FAULT_IPR;
5792 return 0;
5793 }
5794 #if defined(EIS_PTR2)
5795 writeToOutputBuffer(cpup, &e->out, 9, e->dstSZ, EISget49(cpup, &e->ADDR2, &e->mopPos, CTN9));
5796
5797 #else
5798 writeToOutputBuffer(cpup, &e->out, 9, e->dstSZ, EISget49(cpup, e->mopAddress, &e->mopPos, CTN9));
5799
5800 #endif
5801 e->mopTally -= 1;
5802
5803 }
5804 }
5805 return 0;
5806 }
5807
5808
5809
5810
5811
5812
5813
5814
5815
5816
5817
5818 static int mopINSM (cpu_state_t * cpup)
5819 {
5820 EISstruct * e = & cpu.currentEISinstruction;
5821 if (e->mopIF == 0)
5822 e->mopIF = 16;
5823 for(int n = 0 ; n < e->mopIF ; n += 1)
5824 {
5825 if (e->dstTally == 0)
5826 break;
5827 writeToOutputBuffer(cpup, &e->out, 9, e->dstSZ, e->editInsertionTable[0]);
5828 }
5829 return 0;
5830 }
5831
5832
5833
5834
5835
5836
5837
5838
5839
5840
5841
5842
5843
5844
5845
5846
5847
5848
5849 static int mopINSN (cpu_state_t * cpup)
5850 {
5851 EISstruct * e = & cpu.currentEISinstruction;
5852
5853 if (e->mopIF >= 9 )
5854 {
5855 e->_faults |= FAULT_IPR;
5856 return 0;
5857 }
5858
5859
5860
5861
5862
5863 if (e->mopIF == 0)
5864 {
5865 if (e->mopTally == 0)
5866 {
5867 e->_faults |= FAULT_IPR;
5868 return 0;
5869 }
5870 if (!e->mopSN)
5871 {
5872
5873
5874
5875 #if defined(EIS_PTR2)
5876 EISget49(cpup, &e->ADDR2, &e->mopPos, CTN9);
5877 #else
5878 EISget49(cpup, e->mopAddress, &e->mopPos, CTN9);
5879 #endif
5880 writeToOutputBuffer(cpup, &e->out, 9, e->dstSZ, e->editInsertionTable[0]);
5881 e->mopTally -= 1;
5882 } else {
5883
5884
5885
5886 #if defined(EIS_PTR2)
5887 writeToOutputBuffer(cpup, &e->out, 9, e->dstSZ, EISget49(cpup, &e->ADDR2, &e->mopPos, CTN9));
5888 #else
5889 writeToOutputBuffer(cpup, &e->out, 9, e->dstSZ, EISget49(cpup, e->mopAddress, &e->mopPos, CTN9));
5890 #endif
5891
5892 e->mopTally -= 1;
5893 }
5894 }
5895 else
5896 {
5897 if (e->mopSN)
5898 {
5899
5900
5901 writeToOutputBuffer(cpup, &e->out, 9, e->dstSZ, e->editInsertionTable[e->mopIF - 1]);
5902 } else {
5903 writeToOutputBuffer(cpup, &e->out, 9, e->dstSZ, e->editInsertionTable[0]);
5904 }
5905 }
5906 return 0;
5907 }
5908
5909
5910
5911
5912
5913
5914
5915
5916
5917
5918 static int mopINSP (cpu_state_t * cpup)
5919 {
5920 EISstruct * e = & cpu.currentEISinstruction;
5921
5922 if (e->mopIF >= 9 )
5923 {
5924 e->_faults |= FAULT_IPR;
5925 return 0;
5926 }
5927
5928 if (e->mopIF == 0)
5929 {
5930 if (e->mopTally == 0)
5931 {
5932 e->_faults |= FAULT_IPR;
5933 return 0;
5934 }
5935 if (e->mopSN)
5936 {
5937 #if defined(EIS_PTR2)
5938 EISget49(cpup, &e->ADDR2, &e->mopPos, CTN9);
5939 #else
5940 EISget49(cpup, e->mopAddress, &e->mopPos, CTN9);
5941 #endif
5942 writeToOutputBuffer(cpup, &e->out, 9, e->dstSZ, e->editInsertionTable[0]);
5943 e->mopTally -= 1;
5944 } else {
5945 #if defined(EIS_PTR2)
5946 writeToOutputBuffer(cpup, &e->out, 9, e->dstSZ, EISget49(cpup, &e->ADDR2, &e->mopPos, CTN9));
5947 #else
5948 writeToOutputBuffer(cpup, &e->out, 9, e->dstSZ, EISget49(cpup, e->mopAddress, &e->mopPos, CTN9));
5949 #endif
5950 e->mopTally -= 1;
5951 }
5952 }
5953 else
5954 {
5955 if (!e->mopSN)
5956 {
5957 writeToOutputBuffer(cpup, &e->out, 9, e->dstSZ, e->editInsertionTable[e->mopIF - 1]);
5958 } else {
5959 writeToOutputBuffer(cpup, &e->out, 9, e->dstSZ, e->editInsertionTable[0]);
5960 }
5961 }
5962
5963 return 0;
5964 }
5965
5966
5967
5968
5969
5970
5971
5972
5973
5974
5975
5976 static int mopLTE (cpu_state_t * cpup)
5977 {
5978 EISstruct * e = & cpu.currentEISinstruction;
5979 if (e->mopIF == 0 || (e->mopIF >= 9 && e->mopIF <= 15))
5980 {
5981 e->_faults |= FAULT_IPR;
5982 return 0;
5983 }
5984 if (e->mopTally == 0)
5985 {
5986 e->_faults |= FAULT_IPR;
5987 return 0;
5988 }
5989 #if defined(EIS_PTR2)
5990 word9 next = EISget49(cpup, &e->ADDR2, &e->mopPos, CTN9);
5991 #else
5992 word9 next = EISget49(cpup, e->mopAddress, &e->mopPos, CTN9);
5993 #endif
5994 e->mopTally -= 1;
5995
5996
5997 if (e->mopIF - 1 >= 0 &&
5998 e->mopIF - 1 < sizeof(e->editInsertionTable) / sizeof(e->editInsertionTable[0])) {
5999 e->editInsertionTable[e->mopIF - 1] = next;
6000 } else {
6001 e->_faults |= FAULT_IPR;
6002 sim_warn("mopIF %d OOB in %s!\r\n", e->mopIF, __func__);
6003 return 0;
6004 }
6005 sim_debug (DBG_TRACEEXT, & cpu_dev, "LTE IT[%d]<=%d\r\n", e -> mopIF - 1, next);
6006 return 0;
6007 }
6008
6009
6010
6011
6012
6013
6014
6015
6016
6017
6018
6019
6020
6021
6022
6023
6024
6025
6026
6027
6028
6029
6030
6031
6032
6033
6034
6035
6036
6037
6038
6039
6040
6041
6042
6043
6044
6045
6046
6047 static int mopMFLC (cpu_state_t * cpup)
6048 {
6049 EISstruct * e = & cpu.currentEISinstruction;
6050 if (e->mopIF == 0)
6051 e->mopIF = 16;
6052
6053
6054
6055
6056 sim_debug (DBG_TRACEEXT, & cpu_dev, "MFLC IF %d, srcTally %d, dstTally %d\r\n", e->mopIF, e->srcTally, e->dstTally);
6057 for(int n = 0 ; n < e->mopIF ; n += 1)
6058 {
6059 sim_debug (DBG_TRACEEXT, & cpu_dev, "MFLC n %d, srcTally %d, dstTally %d\r\n", n, e->srcTally, e->dstTally);
6060 if (e->dstTally == 0)
6061 break;
6062 if (e->srcTally == 0)
6063 return -1;
6064
6065
6066
6067
6068
6069
6070 word9 c = *(e->in);
6071 sim_debug (DBG_TRACEEXT, & cpu_dev, "MFLC c %d (0%o)\r\n", c, c);
6072 if (!e->mopES) {
6073
6074 sim_debug (DBG_TRACEEXT, & cpu_dev, "MFLC ES off\r\n");
6075 if (isDecimalZero (c)) {
6076 sim_debug (DBG_TRACEEXT, & cpu_dev, "MFLC is zero\r\n");
6077
6078
6079 writeToOutputBuffer(cpup, &e->out, 9, e->dstSZ, e->editInsertionTable[0]);
6080 e->in += 1;
6081 e->srcTally -= 1;
6082 } else {
6083 sim_debug (DBG_TRACEEXT, & cpu_dev, "MFLC is not zero\r\n");
6084
6085
6086
6087 writeToOutputBuffer(cpup, &e->out, 9, e->dstSZ, e->editInsertionTable[4]);
6088
6089 writeToOutputBuffer(cpup, &e->out, e->srcSZ, e->dstSZ, c);
6090 e->mopZ = false;
6091 e->in += 1;
6092 e->srcTally -= 1;
6093
6094 e->mopES = true;
6095 }
6096 } else {
6097 sim_debug (DBG_TRACEEXT, & cpu_dev, "MFLC ES on\r\n");
6098
6099 writeToOutputBuffer(cpup, &e->out, e->srcSZ, e->dstSZ, c);
6100
6101 if (! isDecimalZero (c))
6102 e->mopZ = false;
6103 e->in += 1;
6104 e->srcTally -= 1;
6105 }
6106 }
6107
6108 return 0;
6109 }
6110
6111
6112
6113
6114
6115
6116
6117
6118
6119
6120
6121
6122
6123
6124
6125
6126
6127
6128
6129
6130
6131
6132
6133
6134
6135
6136
6137
6138
6139
6140
6141
6142
6143
6144
6145
6146
6147
6148
6149
6150
6151
6152
6153 static int mopMFLS (cpu_state_t * cpup)
6154 {
6155 EISstruct * e = & cpu.currentEISinstruction;
6156 if (e->mopIF == 0)
6157 e->mopIF = 16;
6158
6159 for(int n = 0 ; n < e->mopIF; n += 1)
6160 {
6161 if (e->dstTally == 0)
6162 break;
6163 if (e->srcTally == 0)
6164 return -1;
6165
6166 word9 c = *(e->in);
6167 sim_debug (DBG_TRACEEXT, & cpu_dev, "MFLS n %d c %o\r\n", n, c);
6168 if (!e->mopES) {
6169 if (isDecimalZero (c))
6170 {
6171
6172
6173 sim_debug (DBG_TRACEEXT, & cpu_dev,
6174 "ES is off, c is zero; edit insertion table entry 1"
6175 " is moved to the receiving field in place of the character.\r\n");
6176 writeToOutputBuffer(cpup, &e->out, 9, e->dstSZ, e->editInsertionTable[0]);
6177 e->in += 1;
6178 e->srcTally -= 1;
6179 } else {
6180
6181 if (!e->mopSN)
6182 {
6183
6184
6185
6186 sim_debug (DBG_TRACEEXT, & cpu_dev,
6187 "ES is off, c is non-zero, SN is off; edit insertion table entry 3"
6188 " is moved to the receiving field; the character is also moved to"
6189 " the receiving field, and ES is set ON.\r\n");
6190 writeToOutputBuffer(cpup, &e->out, 9, e->dstSZ, e->editInsertionTable[2]);
6191
6192 e->in += 1;
6193 e->srcTally -= 1;
6194 e->mopZ = false;
6195
6196
6197
6198
6199
6200
6201
6202
6203 writeToOutputBuffer(cpup, &e->out, e->srcSZ, e->dstSZ, c);
6204
6205 e->mopES = true;
6206 } else {
6207
6208
6209
6210 sim_debug (DBG_TRACEEXT, & cpu_dev,
6211 "ES is off, c is non-zero, SN is OFF; edit insertion table entry 4"
6212 " is moved to the receiving field; the character is also moved to"
6213 " the receiving field, and ES is set ON.\r\n");
6214 writeToOutputBuffer(cpup, &e->out, 9, e->dstSZ, e->editInsertionTable[3]);
6215
6216 e->in += 1;
6217 e->srcTally -= 1;
6218 e->mopZ = false;
6219
6220 writeToOutputBuffer(cpup, &e->out, e->srcSZ, e->dstSZ, c);
6221
6222 e->mopES = true;
6223 }
6224 }
6225 } else {
6226
6227 sim_debug (DBG_TRACEEXT, & cpu_dev, "ES is ON, the character is moved to the receiving field.\r\n");
6228 writeToOutputBuffer(cpup, &e->out, e->srcSZ, e->dstSZ, c);
6229
6230 if (! isDecimalZero (c))
6231 e->mopZ = false;
6232 e->in += 1;
6233 e->srcTally -= 1;
6234 }
6235 }
6236
6237
6238
6239
6240
6241 return 0;
6242 }
6243
6244
6245
6246
6247
6248
6249
6250
6251
6252
6253
6254
6255
6256
6257
6258
6259
6260
6261
6262
6263 static int mopMORS (cpu_state_t * cpup)
6264 {
6265 EISstruct * e = & cpu.currentEISinstruction;
6266 if (e->mopIF == 0)
6267 e->mopIF = 16;
6268
6269 sim_debug (DBG_TRACEEXT, & cpu_dev, "MORS mopIF %d src %d dst %d\r\n", e->mopIF, e->srcTally, e->dstTally);
6270 for(int n = 0 ; n < e->mopIF ; n += 1)
6271 {
6272
6273
6274
6275
6276
6277 if (e->dstTally == 0)
6278 break;
6279 if (e->srcTally == 0)
6280 return -1;
6281
6282
6283 word9 c = (*e->in | (!e->mopSN ? e->editInsertionTable[2] : e->editInsertionTable[3]));
6284 if (! isDecimalZero (*e->in))
6285 e->mopZ = false;
6286 e->in += 1;
6287 e->srcTally -= 1;
6288
6289 writeToOutputBuffer(cpup, &e->out, e->srcSZ, e->dstSZ, c);
6290 }
6291
6292 return 0;
6293 }
6294
6295
6296
6297
6298
6299
6300
6301
6302
6303
6304
6305 static int mopMVC (cpu_state_t * cpup)
6306 {
6307 EISstruct * e = & cpu.currentEISinstruction;
6308 if (e->mopIF == 0)
6309 e->mopIF = 16;
6310
6311 sim_debug (DBG_TRACEEXT, & cpu_dev, "MVC mopIF %d\r\n", e->mopIF);
6312
6313 for(int n = 0 ; n < e->mopIF ; n += 1)
6314 {
6315 sim_debug (DBG_TRACEEXT, & cpu_dev, "MVC n %d srcTally %d dstTally %d\r\n", n, e->srcTally, e->dstTally);
6316
6317
6318 if (e->dstTally == 0)
6319 break;
6320 if (e->srcTally == 0)
6321 return -1;
6322
6323 sim_debug (DBG_TRACEEXT, & cpu_dev, "MVC write to output buffer %o\r\n", *e->in);
6324 writeToOutputBuffer(cpup, &e->out, e->srcSZ, e->dstSZ, *e->in);
6325 if (! isDecimalZero (*e->in))
6326 e->mopZ = false;
6327 e->in += 1;
6328
6329 e->srcTally -= 1;
6330 }
6331
6332 sim_debug (DBG_TRACEEXT, & cpu_dev, "MVC done\r\n");
6333 return 0;
6334 }
6335
6336
6337
6338
6339
6340
6341
6342
6343
6344
6345
6346
6347
6348
6349
6350
6351
6352
6353
6354
6355
6356
6357
6358
6359
6360
6361
6362 static int mopMSES (cpu_state_t * cpup)
6363 {
6364 EISstruct * e = & cpu.currentEISinstruction;
6365 if (e->mvne == true)
6366 return mopMVC (cpup);
6367
6368 if (e->mopIF == 0)
6369 e->mopIF = 16;
6370
6371 int overpunch = false;
6372
6373 for(int n = 0 ; n < e->mopIF ; n += 1)
6374 {
6375 if (e->dstTally == 0)
6376 break;
6377 if (e->srcTally == 0)
6378 return -1;
6379
6380
6381
6382
6383
6384
6385
6386
6387
6388
6389
6390
6391
6392 word9 c = *(e->in);
6393
6394 if (!overpunch) {
6395 if (c & e->editInsertionTable[2])
6396 overpunch = true;
6397
6398 else if (c & e->editInsertionTable[3])
6399 {
6400 e->mopSN = true;
6401 overpunch = true;
6402 }
6403 }
6404
6405 e->in += 1;
6406 e->srcTally -= 1;
6407 if (! isDecimalZero (c))
6408 e->mopZ = false;
6409 writeToOutputBuffer(cpup, &e->out, e->srcSZ, e->dstSZ, c);
6410 }
6411
6412 return 0;
6413 }
6414
6415
6416
6417
6418
6419
6420
6421
6422
6423
6424
6425 static int mopMVZA (cpu_state_t * cpup)
6426 {
6427 EISstruct * e = & cpu.currentEISinstruction;
6428 if (e->mopIF == 0)
6429 e->mopIF = 16;
6430
6431 for(int n = 0 ; n < e->mopIF ; n += 1)
6432 {
6433 if (e->dstTally == 0)
6434 break;
6435 if (e->srcTally == 0)
6436 return -1;
6437
6438 word9 c = *e->in;
6439 e->in += 1;
6440 e->srcTally -= 1;
6441
6442
6443
6444 if (!e->mopES && isDecimalZero (c))
6445 {
6446
6447
6448
6449 writeToOutputBuffer(cpup, &e->out, 9, e->dstSZ, e->editInsertionTable[1]);
6450
6451
6452 }
6453 else if ((! e->mopES) && (! isDecimalZero (c)))
6454 {
6455
6456
6457 e->mopZ = false;
6458 writeToOutputBuffer(cpup, &e->out, e->srcSZ, e->dstSZ, c);
6459
6460 e->mopES = true;
6461 } else if (e->mopES)
6462 {
6463
6464 if (! isDecimalZero (c))
6465 e->mopZ = false;
6466 writeToOutputBuffer(cpup, &e->out, e->srcSZ, e->dstSZ, c);
6467 }
6468 }
6469
6470 return 0;
6471 }
6472
6473
6474
6475
6476
6477
6478
6479
6480
6481
6482
6483
6484
6485
6486
6487
6488
6489
6490
6491 static int mopMVZB (cpu_state_t * cpup)
6492 {
6493 EISstruct * e = & cpu.currentEISinstruction;
6494 if (e->mopIF == 0)
6495 e->mopIF = 16;
6496
6497 for(int n = 0 ; n < e->mopIF ; n += 1)
6498 {
6499 if (e->dstTally == 0)
6500 break;
6501 if (e->srcTally == 0)
6502 return -1;
6503
6504 word9 c = *e->in;
6505 e->srcTally -= 1;
6506 e->in += 1;
6507
6508
6509
6510 if ((!e->mopES) && isDecimalZero (c))
6511 {
6512
6513
6514
6515 writeToOutputBuffer(cpup, &e->out, 9, e->dstSZ, e->editInsertionTable[0]);
6516
6517
6518 }
6519 if ((! e->mopES) && (! isDecimalZero (c)))
6520 {
6521
6522
6523 e->mopZ = false;
6524 writeToOutputBuffer(cpup, &e->out, e->srcSZ, e->dstSZ, c);
6525
6526 e->mopES = true;
6527 } else if (e->mopES)
6528 {
6529
6530 if (! isDecimalZero (c))
6531 e->mopZ = false;
6532 writeToOutputBuffer(cpup, &e->out, e->srcSZ, e->dstSZ, c);
6533 }
6534 }
6535
6536 return 0;
6537 }
6538
6539
6540
6541
6542
6543
6544
6545
6546
6547
6548
6549
6550
6551
6552 static int mopSES (cpu_state_t * cpup)
6553 {
6554 EISstruct * e = & cpu.currentEISinstruction;
6555 if (e->mopIF & 010)
6556 e->mopES = true;
6557 else
6558 e->mopES = false;
6559
6560 if (e->mopIF & 04)
6561 e->mopBZ = true;
6562
6563 return 0;
6564 }
6565
6566
6567 #if !defined(QUIET_UNUSED)
6568 static char * mopCodes [040] =
6569 {
6570
6571 0, "insm", "enf", "ses", "mvzb", "mvza", "mfls", "mflc",
6572 "insb", "insa", "insn", "insp", "ign", "mvc", "mses", "mors",
6573 "lte", "cht", 0, 0, 0, 0, 0, 0,
6574 0, 0, 0, 0, 0, 0, 0, 0
6575 };
6576 #endif
6577
6578 static MOP_struct mopTab[040] = {
6579 {NULL, 0},
6580 {"insm", mopINSM },
6581 {"enf", mopENF },
6582 {"ses", mopSES },
6583 {"mvzb", mopMVZB },
6584 {"mvza", mopMVZA },
6585 {"mfls", mopMFLS },
6586 {"mflc", mopMFLC },
6587 {"insb", mopINSB },
6588 {"insa", mopINSA },
6589 {"insn", mopINSN },
6590 {"insp", mopINSP },
6591 {"ign", mopIGN },
6592 {"mvc", mopMVC },
6593 {"mses", mopMSES },
6594 {"mors", mopMORS },
6595 {"lte", mopLTE },
6596 {"cht", mopCHT },
6597 {NULL, 0},
6598 {NULL, 0},
6599 {NULL, 0},
6600 {NULL, 0},
6601 {NULL, 0},
6602 {NULL, 0},
6603 {NULL, 0},
6604 {NULL, 0},
6605 {NULL, 0},
6606 {NULL, 0},
6607 {NULL, 0},
6608 {NULL, 0},
6609 {NULL, 0},
6610 {NULL, 0}
6611 };
6612
6613
6614
6615
6616
6617 static MOP_struct* EISgetMop (cpu_state_t * cpup)
6618 {
6619 EISstruct * e = & cpu.currentEISinstruction;
6620
6621
6622
6623 if (e == NULL)
6624
6625
6626
6627 return NULL;
6628
6629
6630 #if defined(EIS_PTR2)
6631 EISaddr *p = &e->ADDR2;
6632 #else
6633 EISaddr *p = e->mopAddress;
6634 #endif
6635
6636
6637 p->data = EISRead(cpup, p);
6638
6639 if (e->mopPos > 3)
6640 {
6641 e->mopPos = 0;
6642 #if defined(EIS_PTR2)
6643 cpu.du.Dk_PTR_W[KMOP] = (cpu.du.Dk_PTR_W[KMOP] + 1) & AMASK;
6644 p->data = EISRead(cpup, &e->ADDR2);
6645 #else
6646 PNL (cpu.du.Dk_PTR_W[1] = (cpu.du.Dk_PTR_W[1] + 1) & AMASK);
6647 PNL (p->data = EISRead(cpup, e->mopAddress));
6648 # if defined(EIS_PTR)
6649 cpu.du.Dk_PTR_W[1] = (cpu.du.Dk_PTR_W[1] + 1) & AMASK;
6650 p->data = EISRead(cpup, e->mopAddress);
6651 # else
6652 e->mopAddress->address = (e->mopAddress->address + 1) & AMASK;
6653 p->data = EISRead(cpup, e->mopAddress);
6654 # endif
6655 #endif
6656 }
6657
6658 word9 mop9 = (word9) get9 (p -> data, e -> mopPos);
6659 word5 mop = (mop9 >> 4) & 037;
6660 e->mopIF = mop9 & 0xf;
6661
6662 MOP_struct *m = &mopTab[mop];
6663 sim_debug (DBG_TRACEEXT, & cpu_dev, "MOP %s(%o) %o\r\n", m -> mopName, mop, e->mopIF);
6664 e->m = m;
6665 if (e->m == NULL || e->m->f == NULL)
6666 {
6667 sim_debug (DBG_TRACEEXT, & cpu_dev, "getMop(e->m == NULL || e->m->f == NULL): mop:%d IF:%d\r\n", mop, e->mopIF);
6668 return NULL;
6669 }
6670
6671 e->mopPos += 1;
6672 e->mopTally -= 1;
6673
6674
6675
6676 return m;
6677 }
6678
6679 #if defined(EIS_PTR2)
6680 static void mopExecutor (cpu_state_t * cpup)
6681 #else
6682 static void mopExecutor (cpu_state_t * cpup, int kMop)
6683 #endif
6684 {
6685 EISstruct * e = & cpu.currentEISinstruction;
6686 PNL (L68_ (DU_CYCLE_FEXOP;))
6687 #if defined(EIS_PTR2)
6688 e->mopTally = (int) e->N[KMOP];
6689 e->mopPos = (int) e->CN[KMOP];
6690 #else
6691 e->mopAddress = &e->addr[kMop-1];
6692 e->mopTally = (int) e->N[kMop-1];
6693 e->mopPos = (int) e->CN[kMop-1];
6694 #endif
6695
6696 word9 *p9 = e->editInsertionTable;
6697 char *q = defaultEditInsertionTable;
6698 while((*p9++ = (word9) (*q++)))
6699 ;
6700
6701 e->in = e->inBuffer;
6702 e->out = e->outBuffer;
6703
6704 e->_faults = 0;
6705
6706
6707
6708
6709
6710
6711
6712
6713 while (e->dstTally)
6714 {
6715 sim_debug (DBG_TRACEEXT, & cpu_dev,
6716 "mopExecutor srcTally %d dstTally %d mopTally %d\r\n",
6717 e->srcTally, e->dstTally, e->mopTally);
6718 MOP_struct *m = EISgetMop(cpup);
6719 if (! m)
6720 {
6721 sim_debug (DBG_TRACEEXT, & cpu_dev, "mopExecutor EISgetMop forced break\r\n");
6722 e->_faults |= FAULT_IPR;
6723 break;
6724 }
6725 int mres = m->f(cpup);
6726
6727
6728 if (e->_faults & FAULT_IPR)
6729 break;
6730
6731
6732
6733
6734
6735
6736
6737
6738
6739
6740
6741
6742
6743
6744
6745
6746
6747
6748
6749
6750 if (e->mopTally == 0 || mres)
6751 {
6752 sim_debug (DBG_TRACEEXT, & cpu_dev,
6753 "mopExecutor N1 or N2 exhausted\r\n");
6754
6755 if (e->mopZ && e->mopBZ)
6756 {
6757 e->out = e->outBuffer;
6758 e->dstTally = (int) e->N3;
6759 while (e->dstTally)
6760 {
6761 writeToOutputBuffer(cpup, &e->out, 9, e->dstSZ, e->editInsertionTable[0]);
6762 }
6763 }
6764 else if (mres || e->dstTally)
6765 {
6766 e->_faults |= FAULT_IPR;
6767 }
6768 break;
6769 }
6770 }
6771
6772 sim_debug (DBG_TRACEEXT, & cpu_dev, "mop faults %o src %d dst %d mop %d\r\n",
6773 e->_faults, e->srcTally, e->dstTally, e->mopTally);
6774
6775
6776
6777
6778
6779
6780
6781
6782
6783
6784
6785
6786
6787
6788
6789
6790
6791
6792
6793
6794
6795
6796
6797
6798
6799
6800
6801
6802
6803
6804
6805
6806
6807
6808
6809
6810
6811
6812
6813
6814
6815
6816
6817
6818
6819
6820
6821 if (e -> _faults)
6822 doFault (FAULT_IPR, fst_ill_proc, "mopExecutor");
6823 }
6824
6825 void mve (cpu_state_t * cpup)
6826 {
6827 EISstruct * e = & cpu.currentEISinstruction;
6828
6829 sim_debug(DBG_TRACEEXT, & cpu_dev, "mve\r\n");
6830
6831 fault_ipr_subtype_ mod_fault = 0;
6832
6833 #if !defined(EIS_SETUP)
6834 setupOperandDescriptor(cpup, 1, &mod_fault);
6835 setupOperandDescriptor(cpup, 2, &mod_fault);
6836 setupOperandDescriptor(cpup, 3, &mod_fault);
6837 #endif
6838
6839 parseAlphanumericOperandDescriptor(cpup, 1, 1, false, &mod_fault);
6840 parseAlphanumericOperandDescriptor(cpup, 2, 2, false, &mod_fault);
6841 parseAlphanumericOperandDescriptor(cpup, 3, 3, false, &mod_fault);
6842
6843 L68_ (
6844
6845 if (mod_fault)
6846 {
6847 doFault (FAULT_IPR,
6848 (_fault_subtype) {.fault_ipr_subtype=mod_fault},
6849 "Illegal modifier");
6850 }
6851 )
6852
6853
6854
6855 if (IWB_IRODD & 0600600000000)
6856 doFault (FAULT_IPR, (_fault_subtype) {.fault_ipr_subtype=FR_ILL_OP|mod_fault}, "mve: 0, 1, 9, 10 MBZ");
6857
6858
6859 if (!(e->MF[0] & MFkID) && e -> op [0] & 0000000010000)
6860 doFault (FAULT_IPR, (_fault_subtype) {.fault_ipr_subtype=FR_ILL_PROC|mod_fault}, "mve op1 23 MBZ");
6861
6862
6863
6864
6865
6866
6867
6868 if (!(e->MF[1] & MFkID) && e -> op [1] & 0000000010000)
6869 doFault (FAULT_IPR, (_fault_subtype) {.fault_ipr_subtype=FR_ILL_PROC|mod_fault}, "mve op2 23 MBZ");
6870
6871
6872 if (!(e->MF[2] & MFkID) && e -> op [2] & 0000000010000)
6873 doFault (FAULT_IPR, (_fault_subtype) {.fault_ipr_subtype=FR_ILL_PROC|mod_fault}, "mve op3 23 MBZ");
6874
6875 DPS8M_ (
6876
6877 if (mod_fault)
6878 {
6879 doFault (FAULT_IPR,
6880 (_fault_subtype) {.fault_ipr_subtype=mod_fault},
6881 "Illegal modifier");
6882 }
6883 )
6884
6885
6886 e->mopES = false;
6887 e->mopSN = false;
6888 e->mopBZ = false;
6889 e->mopZ = true;
6890
6891 e->srcTally = (int) e->N1;
6892 e->dstTally = (int) e->N3;
6893
6894 #if defined(EIS_PTR3)
6895 e->srcTA = (int) TA1;
6896 #else
6897 e->srcTA = (int) e->TA1;
6898 #endif
6899
6900 switch (e -> srcTA)
6901 {
6902 case CTA4:
6903 e -> srcSZ = 4;
6904 break;
6905 case CTA6:
6906 e -> srcSZ = 6;
6907 break;
6908 case CTA9:
6909 e -> srcSZ = 9;
6910 break;
6911 }
6912
6913 #if defined(EIS_PTR3)
6914 uint dstTA = TA3;
6915 #else
6916 uint dstTA = e -> TA3;
6917 #endif
6918
6919 switch (dstTA)
6920 {
6921 case CTA4:
6922 e -> dstSZ = 4;
6923 break;
6924 case CTA6:
6925 e -> dstSZ = 6;
6926 break;
6927 case CTA9:
6928 e -> dstSZ = 9;
6929 break;
6930 }
6931
6932
6933 EISloadInputBufferAlphnumeric (cpup, 1);
6934
6935
6936 e -> mvne = false;
6937
6938 #if defined(EIS_PTR2)
6939 mopExecutor (cpup);
6940 #else
6941 mopExecutor (cpup, 2);
6942 #endif
6943
6944 e -> dstTally = (int) e -> N3;
6945
6946 EISwriteOutputBufferToMemory (cpup, 3);
6947 cleanupOperandDescriptor (cpup, 1);
6948 cleanupOperandDescriptor (cpup, 2);
6949 cleanupOperandDescriptor (cpup, 3);
6950 }
6951
6952 void mvne (cpu_state_t * cpup)
6953 {
6954 EISstruct * e = & cpu.currentEISinstruction;
6955
6956 fault_ipr_subtype_ mod_fault = 0;
6957
6958 #if !defined(EIS_SETUP)
6959 setupOperandDescriptor (cpup, 1, &mod_fault);
6960 setupOperandDescriptor (cpup, 2, &mod_fault);
6961 setupOperandDescriptor (cpup, 3, &mod_fault);
6962 #endif
6963
6964 parseNumericOperandDescriptor (cpup, 1, &mod_fault);
6965 parseAlphanumericOperandDescriptor (cpup, 2, 2, false, &mod_fault);
6966 parseAlphanumericOperandDescriptor (cpup, 3, 3, false, &mod_fault);
6967
6968 L68_ (
6969
6970 if (mod_fault)
6971 {
6972 doFault (FAULT_IPR,
6973 (_fault_subtype) {.fault_ipr_subtype=mod_fault},
6974 "Illegal modifier");
6975 }
6976 )
6977
6978
6979 if (IWB_IRODD & 0600600000000)
6980 doFault (FAULT_IPR, (_fault_subtype) {.fault_ipr_subtype=FR_ILL_OP|mod_fault}, "mvne: 0, 1, 9, 10 MBZ");
6981
6982
6983
6984
6985
6986
6987
6988
6989
6990
6991
6992
6993 if (!(e->MF[1] & MFkID) && e -> op [1] & 0000000070000)
6994 doFault (FAULT_IPR, (_fault_subtype) {.fault_ipr_subtype=FR_ILL_PROC|mod_fault}, "mvne op2 21-23 MBZ");
6995
6996
6997
6998
6999
7000
7001
7002 if (!(e->MF[2] & MFkID) && e -> op [2] & 0000000010000)
7003 doFault (FAULT_IPR, (_fault_subtype) {.fault_ipr_subtype=FR_ILL_PROC|mod_fault}, "mvne op3 23 MBZ");
7004
7005 DPS8M_ (
7006
7007 if (mod_fault)
7008 {
7009 doFault (FAULT_IPR,
7010 (_fault_subtype) {.fault_ipr_subtype=mod_fault},
7011 "Illegal modifier");
7012 }
7013 )
7014
7015 uint srcTN = e -> TN1;
7016
7017 int n1 = 0;
7018
7019
7020
7021
7022
7023
7024
7025
7026
7027
7028
7029 switch(e->S1)
7030 {
7031 case CSFL:
7032 n1 = (int) e->N1 - 1;
7033 if (srcTN == CTN4)
7034 n1 -= 2;
7035 else
7036 n1 -= 1;
7037 break;
7038
7039 case CSLS:
7040 case CSTS:
7041 n1 = (int) e->N1 - 1;
7042 break;
7043
7044 case CSNS:
7045 n1 = (int) e->N1;
7046 break;
7047 }
7048
7049 if (n1 < 1)
7050 doFault (FAULT_IPR, fst_ill_proc, "mvne adjusted n1<1");
7051
7052
7053
7054
7055 if (e->N[1] == 0)
7056 doFault (FAULT_IPR, fst_ill_proc, "mvne N2 0");
7057
7058
7059
7060 if (e->N[2] == 0)
7061 doFault (FAULT_IPR, fst_ill_proc, "mvne N3 0");
7062
7063
7064
7065
7066
7067
7068
7069
7070
7071
7072
7073
7074
7075
7076
7077
7078 e->mopES = false;
7079 e->mopSN = false;
7080 e->mopBZ = false;
7081 e->mopZ = true;
7082
7083 e -> srcTally = (int) e -> N1;
7084 e -> dstTally = (int) e -> N3;
7085
7086
7087
7088
7089
7090 e->srcTA = CTA4;
7091
7092 switch(srcTN)
7093 {
7094 case CTN4:
7095
7096 e->srcSZ = 4;
7097 break;
7098 case CTN9:
7099
7100 e->srcSZ = 4;
7101 break;
7102 }
7103
7104 #if defined(EIS_PTR3)
7105 uint dstTA = TA3;
7106 #else
7107 uint dstTA = e->TA3;
7108 #endif
7109 switch(dstTA)
7110 {
7111 case CTA4:
7112
7113 e->dstSZ = 4;
7114 break;
7115 case CTA6:
7116
7117 e->dstSZ = 6;
7118 break;
7119 case CTA9:
7120
7121 e->dstSZ = 9;
7122 break;
7123 }
7124
7125 #if defined(EIS_PTR3)
7126 sim_debug (DBG_TRACEEXT, & cpu_dev,
7127 "mvne N1 %d N2 %d N3 %d TN1 %d CN1 %d TA3 %d CN3 %d\r\n",
7128 e->N1, e->N2, e->N3, e->TN1, e->CN1, TA3, e->CN3);
7129 #else
7130 sim_debug (DBG_TRACEEXT, & cpu_dev,
7131 "mvne N1 %d N2 %d N3 %d TN1 %d CN1 %d TA3 %d CN3 %d\r\n",
7132 e->N1, e->N2, e->N3, e->TN1, e->CN1, e->TA3, e->CN3);
7133 #endif
7134
7135
7136 EISloadInputBufferNumeric (cpup, 1);
7137
7138
7139
7140
7141
7142
7143
7144
7145
7146
7147 int sum = 0;
7148 for(int n = 0 ; n < e -> srcTally ; n ++)
7149 sum += e -> inBuffer [n];
7150 if ((e -> sign == -1) && sum)
7151 e -> mopSN = true;
7152
7153
7154 e -> mvne = true;
7155
7156 #if defined(EIS_PTR2)
7157 mopExecutor (cpup);
7158 #else
7159 mopExecutor (cpup, 2);
7160 #endif
7161
7162 e -> dstTally = (int) e -> N3;
7163
7164 EISwriteOutputBufferToMemory (cpup, 3);
7165 cleanupOperandDescriptor (cpup, 1);
7166 cleanupOperandDescriptor (cpup, 2);
7167 cleanupOperandDescriptor (cpup, 3);
7168 }
7169
7170
7171
7172
7173
7174 void mvt (cpu_state_t * cpup)
7175 {
7176 EISstruct * e = & cpu.currentEISinstruction;
7177
7178
7179
7180
7181
7182
7183
7184
7185
7186
7187 fault_ipr_subtype_ mod_fault = 0;
7188
7189 #if !defined(EIS_SETUP)
7190 setupOperandDescriptor (cpup, 1, &mod_fault);
7191 setupOperandDescriptor (cpup, 2, &mod_fault);
7192 setupOperandDescriptorCache (cpup,3);
7193 #endif
7194
7195 parseAlphanumericOperandDescriptor (cpup, 1, 1, false, &mod_fault);
7196 parseAlphanumericOperandDescriptor (cpup, 2, 2, false, &mod_fault);
7197 parseArgOperandDescriptor (cpup, 3, &mod_fault);
7198
7199 L68_ (
7200
7201 if (mod_fault)
7202 {
7203 doFault (FAULT_IPR,
7204 (_fault_subtype) {.fault_ipr_subtype=mod_fault},
7205 "Illegal modifier");
7206 }
7207 )
7208
7209
7210
7211
7212
7213 if (IWB_IRODD & 0000200000000)
7214 {
7215
7216 doFault (FAULT_IPR, (_fault_subtype) {.fault_ipr_subtype=FR_ILL_OP|mod_fault}, "mvt 10 MBZ");
7217 }
7218
7219
7220
7221
7222
7223
7224
7225
7226
7227
7228 if (!(e->MF[0] & MFkID) && e -> op [0] & 0000000010000)
7229 doFault (FAULT_IPR, (_fault_subtype) {.fault_ipr_subtype=FR_ILL_PROC|mod_fault}, "mvt op1 23 MBZ");
7230
7231
7232
7233
7234
7235
7236
7237
7238
7239 if (!(e->MF[2] & MFkID) && e -> op [2] & 0000000777600)
7240 doFault (FAULT_IPR, (_fault_subtype) {.fault_ipr_subtype=FR_ILL_PROC|mod_fault}, "mvt op3 18-28 MBZ");
7241
7242 DPS8M_ (
7243
7244 if (mod_fault)
7245 {
7246 doFault (FAULT_IPR,
7247 (_fault_subtype) {.fault_ipr_subtype=mod_fault},
7248 "Illegal modifier");
7249 }
7250 )
7251
7252 #if defined(EIS_PTR3)
7253 e->srcTA = (int) TA1;
7254 uint dstTA = TA2;
7255
7256 switch (TA1)
7257 #else
7258 e->srcTA = (int) e->TA1;
7259 uint dstTA = e->TA2;
7260
7261 switch (e -> TA1)
7262 #endif
7263 {
7264 case CTA4:
7265 e -> srcSZ = 4;
7266 break;
7267 case CTA6:
7268 e -> srcSZ = 6;
7269 break;
7270 case CTA9:
7271 e -> srcSZ = 9;
7272 break;
7273 }
7274
7275 #if defined(EIS_PTR3)
7276 switch (TA2)
7277 #else
7278 switch (e -> TA2)
7279 #endif
7280 {
7281 case CTA4:
7282 e -> dstSZ = 4;
7283 break;
7284 case CTA6:
7285 e -> dstSZ = 6;
7286 break;
7287 case CTA9:
7288 e -> dstSZ = 9;
7289 break;
7290 }
7291
7292
7293
7294
7295
7296
7297
7298
7299
7300
7301
7302
7303
7304
7305 uint xlatSize = 0;
7306 #if defined(EIS_PTR3)
7307 switch(TA1)
7308 #else
7309 switch(e->TA1)
7310 #endif
7311 {
7312 case CTA4:
7313 xlatSize = 4;
7314 break;
7315 case CTA6:
7316 xlatSize = 16;
7317 break;
7318 case CTA9:
7319 xlatSize = 128;
7320 break;
7321 }
7322
7323
7324
7325
7326
7327
7328
7329
7330
7331
7332
7333 int lastpageidx = ((int)e->N1 + (int)e->CN1 -1) / e->srcSZ;
7334 if (lastpageidx>0)
7335 EISReadIdx(cpup, &e->ADDR1, (uint)lastpageidx);
7336
7337 if (xlatSize > 0)
7338 {
7339 EISReadIdx(cpup, &e->ADDR3, 0);
7340 EISReadIdx(cpup, &e->ADDR3, xlatSize-1);
7341 }
7342
7343 word1 T = getbits36_1 (cpu.cu.IWB, 9);
7344
7345 word9 fill = getbits36_9 (cpu.cu.IWB, 0);
7346 word9 fillT = fill;
7347
7348 switch(e->srcSZ)
7349 {
7350 case 4:
7351 fillT = fill & 017;
7352 break;
7353 case 6:
7354 fillT = fill & 077;
7355 break;
7356 }
7357
7358 sim_debug (DBG_TRACEEXT, & cpu_dev,
7359 "%s srcCN:%d dstCN:%d srcSZ:%d dstSZ:%d T:%d fill:%03o/%03o N1:%d N2:%d\r\n",
7360 __func__, e -> CN1, e -> CN2, e -> srcSZ, e -> dstSZ, T,
7361 fill, fillT, e -> N1, e -> N2);
7362
7363 PNL (L68_ (if (max (e->N1, e->N2) < 128)
7364 DU_CYCLE_FLEN_128;))
7365
7366 for ( ; cpu.du.CHTALLY < min(e->N1, e->N2); cpu.du.CHTALLY ++)
7367 {
7368 tandd_eis_sample (cpup, cpu.du.CHTALLY, TDPER (e -> TA2));
7369 word9 c = EISget469(cpup, 1, cpu.du.CHTALLY);
7370 int cidx = 0;
7371
7372 #if defined(EIS_PTR3)
7373 if (TA1 == TA2)
7374 #else
7375 if (e->TA1 == e->TA2)
7376 #endif
7377 EISput469(cpup, 2, cpu.du.CHTALLY, xlate (cpup, &e->ADDR3, dstTA, c));
7378 else
7379 {
7380
7381
7382
7383 cidx = c;
7384
7385 word9 cout = xlate(cpup, &e->ADDR3, dstTA, (uint) cidx);
7386
7387
7388
7389
7390
7391
7392
7393
7394
7395
7396
7397 switch (e->srcSZ)
7398 {
7399 case 6:
7400 switch(e->dstSZ)
7401 {
7402 case 4:
7403 cout &= 017;
7404 break;
7405 case 9:
7406 break;
7407 }
7408 break;
7409 case 9:
7410 switch(e->dstSZ)
7411 {
7412 case 4:
7413 cout &= 017;
7414 break;
7415 case 6:
7416 cout &= 077;
7417 break;
7418 }
7419 break;
7420 }
7421
7422 EISput469 (cpup, 2, cpu.du.CHTALLY, cout);
7423 }
7424 }
7425
7426
7427
7428
7429
7430 if (e->N1 < e->N2)
7431 {
7432 word9 cfill = xlate(cpup, &e->ADDR3, dstTA, fillT);
7433 switch (e->srcSZ)
7434 {
7435 case 6:
7436 switch(e->dstSZ)
7437 {
7438 case 4:
7439 cfill &= 017;
7440 break;
7441 case 9:
7442 break;
7443 }
7444 break;
7445 case 9:
7446 switch(e->dstSZ)
7447 {
7448 case 4:
7449 cfill &= 017;
7450 break;
7451 case 6:
7452 cfill &= 077;
7453 break;
7454 }
7455 break;
7456 }
7457
7458 for( ; cpu.du.CHTALLY < e->N2 ; cpu.du.CHTALLY ++)
7459 {
7460 tandd_eis_sample (cpup, cpu.du.CHTALLY, TDPER (e -> TA2));
7461 EISput469 (cpup, 2, cpu.du.CHTALLY, cfill);
7462 }
7463 }
7464
7465 cleanupOperandDescriptor (cpup, 1);
7466 cleanupOperandDescriptor (cpup, 2);
7467 cleanupOperandDescriptor (cpup, 3);
7468
7469 if (e->N1 > e->N2)
7470 {
7471 SET_I_TRUNC;
7472 if (T && ! TST_I_OMASK)
7473 doFault(FAULT_OFL, fst_zero, "mvt truncation fault");
7474 }
7475 else
7476 CLR_I_TRUNC;
7477 }
7478
7479
7480
7481
7482
7483 void cmpn (cpu_state_t * cpup)
7484 {
7485 EISstruct * e = & cpu.currentEISinstruction;
7486
7487
7488
7489
7490
7491
7492
7493 fault_ipr_subtype_ mod_fault = 0;
7494
7495 #if !defined(EIS_SETUP)
7496 setupOperandDescriptor(cpup, 1, &mod_fault);
7497 setupOperandDescriptor(cpup, 2, &mod_fault);
7498 #endif
7499
7500 parseNumericOperandDescriptor(cpup, 1, &mod_fault);
7501 parseNumericOperandDescriptor(cpup, 2, &mod_fault);
7502
7503 L68_ (
7504
7505 if (mod_fault)
7506 {
7507 doFault (FAULT_IPR,
7508 (_fault_subtype) {.fault_ipr_subtype=mod_fault},
7509 "Illegal modifier");
7510 }
7511 )
7512
7513
7514 if (IWB_IRODD & 0777600000000)
7515 doFault (FAULT_IPR, (_fault_subtype) {.fault_ipr_subtype=FR_ILL_OP|mod_fault}, "cmpn 0-10 MBZ");
7516
7517 DPS8M_ (
7518
7519 if (mod_fault)
7520 {
7521 doFault (FAULT_IPR,
7522 (_fault_subtype) {.fault_ipr_subtype=mod_fault},
7523 "Illegal modifier");
7524 }
7525 )
7526
7527 uint srcTN = e->TN1;
7528
7529 int n1 = 0, n2 = 0, sc1 = 0, sc2 = 0;
7530
7531
7532
7533
7534
7535
7536
7537
7538
7539
7540
7541 switch(e->S1)
7542 {
7543 case CSFL:
7544 n1 = (int) e->N1 - 1;
7545 if (srcTN == CTN4)
7546 n1 -= 2;
7547 else
7548 n1 -= 1;
7549 sc1 = 0;
7550 break;
7551
7552 case CSLS:
7553 case CSTS:
7554 n1 = (int) e->N1 - 1;
7555 sc1 = -e->SF1;
7556 break;
7557
7558 case CSNS:
7559 n1 = (int) e->N1;
7560 sc1 = -e->SF1;
7561 break;
7562 }
7563
7564 if (n1 < 1)
7565 doFault (FAULT_IPR, fst_ill_proc, "cmpn adjusted n1<1");
7566
7567 switch(e->S2)
7568 {
7569 case CSFL:
7570 n2 = (int) e->N2 - 1;
7571 if (e->TN2 == CTN4)
7572 n2 -= 2;
7573 else
7574 n2 -= 1;
7575 sc2 = 0;
7576 break;
7577
7578 case CSLS:
7579 case CSTS:
7580 n2 = (int) e->N2 - 1;
7581 sc2 = -e->SF2;
7582 break;
7583
7584 case CSNS:
7585 n2 = (int) e->N2;
7586 sc2 = -e->SF2;
7587 break;
7588 }
7589
7590 if (n2 < 1)
7591 doFault (FAULT_IPR, fst_ill_proc, "cmpn adjusted n2<1");
7592
7593 decContext set;
7594
7595 decContextDefaultDPS8(&set);
7596
7597 set.traps=0;
7598
7599 decNumber _1, _2, _3;
7600
7601 EISloadInputBufferNumeric (cpup, 1);
7602
7603 decNumber *op1 = decBCD9ToNumber(e->inBuffer, n1, sc1, &_1);
7604 if (e->sign == -1)
7605 op1->bits |= DECNEG;
7606 if (e->S1 == CSFL)
7607 op1->exponent = e->exponent;
7608
7609 EISloadInputBufferNumeric (cpup, 2);
7610
7611 decNumber *op2 = decBCD9ToNumber(e->inBuffer, n2, sc2, &_2);
7612 if (e->sign == -1)
7613 op2->bits |= DECNEG;
7614 if (e->S2 == CSFL)
7615 op2->exponent = e->exponent;
7616
7617
7618 decNumber *cmp = decNumberCompare(&_3, op1, op2, &set);
7619 int cSigned = decNumberToInt32(cmp, &set);
7620
7621
7622 op1 = decNumberAbs(op1, op1, &set);
7623 op2 = decNumberAbs(op2, op2, &set);
7624
7625
7626 decNumber *mcmp = decNumberCompare(&_3, op1, op2, &set);
7627 int cMag = decNumberToInt32(mcmp, &set);
7628
7629
7630
7631
7632
7633 SC_I_ZERO (cSigned == 0);
7634 SC_I_NEG (cSigned == 1);
7635 SC_I_CARRY (cMag != 1);
7636
7637 cleanupOperandDescriptor (cpup, 1);
7638 cleanupOperandDescriptor (cpup, 2);
7639 }
7640
7641
7642
7643
7644
7645
7646
7647
7648
7649 static void EISwrite4(cpu_state_t * cpup, EISaddr *p, int *pos, word4 char4)
7650 {
7651 word36 w;
7652 if (*pos > 7)
7653 {
7654 *pos = 0;
7655 #if defined(EIS_PTR)
7656 long eisaddr_idx = EISADDR_IDX (p);
7657 if (eisaddr_idx < 0 || eisaddr_idx > 2) { sim_warn ("IDX1"); return }
7658 cpu.du.Dk_PTR_W[eisaddr_idx] = (cpu.du.Dk_PTR_W[eisaddr_idx] + 1) & AMASK;
7659 #else
7660 p->address = (p->address + 1) & AMASK;
7661 #endif
7662 }
7663
7664 w = EISRead(cpup, p);
7665
7666
7667 switch (*pos)
7668 {
7669 case 0:
7670
7671 w = setbits36_4 (w, 1, char4);
7672 break;
7673 case 1:
7674
7675 w = setbits36_4 (w, 5, char4);
7676 break;
7677 case 2:
7678
7679 w = setbits36_4 (w, 10, char4);
7680 break;
7681 case 3:
7682
7683 w = setbits36_4 (w, 14, char4);
7684 break;
7685 case 4:
7686
7687 w = setbits36_4 (w, 19, char4);
7688 break;
7689 case 5:
7690
7691 w = setbits36_4 (w, 23, char4);
7692 break;
7693 case 6:
7694
7695 w = setbits36_4 (w, 28, char4);
7696 break;
7697 case 7:
7698
7699 w = setbits36_4 (w, 32, char4);
7700 break;
7701 }
7702
7703 EISWriteIdx(cpup, p, 0, w, true);
7704
7705 *pos += 1;
7706 }
7707
7708
7709
7710
7711
7712 static void EISwrite9(cpu_state_t *cpup, EISaddr *p, int *pos, word9 char9)
7713 {
7714 word36 w;
7715 if (*pos > 3)
7716 {
7717 *pos = 0;
7718 #if defined(EIS_PTR)
7719 long eisaddr_idx = EISADDR_IDX (p);
7720 if (eisaddr_idx < 0 || eisaddr_idx > 2) { sim_warn ("IDX1"); return }
7721 cpu.du.Dk_PTR_W[eisaddr_idx] = (cpu.du.Dk_PTR_W[eisaddr_idx] + 1) & AMASK;
7722 #else
7723 p->address = (p->address + 1) & AMASK;
7724 #endif
7725 }
7726
7727 w = EISRead(cpup, p);
7728
7729
7730 switch (*pos)
7731 {
7732 case 0:
7733
7734 w = setbits36_9 (w, 0, char9);
7735 break;
7736 case 1:
7737
7738 w = setbits36_9 (w, 9, char9);
7739 break;
7740 case 2:
7741
7742 w = setbits36_9 (w, 18, char9);
7743 break;
7744 case 3:
7745
7746 w = setbits36_9 (w, 27, char9);
7747 break;
7748 }
7749
7750 EISWriteIdx (cpup, p, 0, w, true);
7751
7752 *pos += 1;
7753 }
7754
7755
7756
7757
7758
7759 static void EISwrite49(cpu_state_t * cpup, EISaddr *p, int *pos, int tn, word9 c49)
7760 {
7761 switch(tn)
7762 {
7763 case CTN4:
7764 EISwrite4(cpup, p, pos, (word4) c49);
7765 return;
7766 case CTN9:
7767 EISwrite9(cpup, p, pos, c49);
7768 return;
7769 }
7770 }
7771
7772 void mvn (cpu_state_t * cpup)
7773 {
7774
7775
7776
7777
7778
7779
7780
7781
7782
7783
7784
7785
7786
7787
7788
7789
7790
7791 EISstruct * e = & cpu.currentEISinstruction;
7792
7793 fault_ipr_subtype_ mod_fault = 0;
7794
7795 #if !defined(EIS_SETUP)
7796 setupOperandDescriptor(cpup, 1, &mod_fault);
7797 setupOperandDescriptor(cpup, 2, &mod_fault);
7798 #endif
7799
7800 parseNumericOperandDescriptor(cpup, 1, &mod_fault);
7801 parseNumericOperandDescriptor(cpup, 2, &mod_fault);
7802
7803 L68_ (
7804
7805 if (mod_fault)
7806 {
7807 doFault (FAULT_IPR,
7808 (_fault_subtype) {.fault_ipr_subtype=mod_fault},
7809 "Illegal modifier");
7810 }
7811 )
7812
7813
7814 if (IWB_IRODD & 0377000000000)
7815 doFault (FAULT_IPR,
7816 (_fault_subtype) {.fault_ipr_subtype=FR_ILL_OP|mod_fault},
7817 "mvn 2-8 MBZ");
7818
7819 DPS8M_ (
7820
7821 if (mod_fault)
7822 {
7823 doFault (FAULT_IPR,
7824 (_fault_subtype) {.fault_ipr_subtype=mod_fault},
7825 "Illegal modifier");
7826 }
7827 )
7828
7829 e->P = getbits36_1 (cpu.cu.IWB, 0) != 0;
7830
7831 word1 T = getbits36_1 (cpu.cu.IWB, 9);
7832 bool R = getbits36_1 (cpu.cu.IWB, 10) != 0;
7833 PNL (L68_ (if (R)
7834 DU_CYCLE_FRND;))
7835
7836 uint srcTN = e->TN1;
7837
7838 uint dstTN = e->TN2;
7839 uint dstCN = e->CN2;
7840
7841 sim_debug (DBG_CAC, & cpu_dev,
7842 "mvn(1): TN1 %d CN1 %d N1 %d TN2 %d CN2 %d N2 %d\r\n",
7843 e->TN1, e->CN1, e->N1, e->TN2, e->CN2, e->N2);
7844 sim_debug (DBG_CAC, & cpu_dev,
7845 "mvn(2): SF1 %d SF2 %d\r\n",
7846 e->SF1, e->SF2);
7847 sim_debug (DBG_CAC, & cpu_dev,
7848 "mvn(3): OP1 %012"PRIo64" OP2 %012"PRIo64"\r\n",
7849 e->OP1, e->OP2);
7850
7851 int n1 = 0, n2 = 0, sc1 = 0;
7852
7853
7854
7855
7856
7857
7858
7859
7860
7861
7862
7863 switch(e->S1)
7864 {
7865 case CSFL:
7866 n1 = (int) e->N1 - 1;
7867 if (srcTN == CTN4)
7868 n1 -= 2;
7869 else
7870 n1 -= 1;
7871 sc1 = 0;
7872 break;
7873
7874 case CSLS:
7875 case CSTS:
7876 n1 = (int) e->N1 - 1;
7877 sc1 = -e->SF1;
7878 break;
7879
7880 case CSNS:
7881 n1 = (int) e->N1;
7882 sc1 = -e->SF1;
7883 break;
7884 }
7885
7886 sim_debug (DBG_CAC, & cpu_dev, "n1 %d sc1 %d\r\n", n1, sc1);
7887
7888
7889
7890
7891
7892
7893
7894 if (n1 < 1)
7895 doFault (FAULT_IPR, fst_ill_proc, "mvn adjusted n1<1");
7896
7897 switch(e->S2)
7898 {
7899 case CSFL:
7900 n2 = (int) e->N2 - 1;
7901 if (dstTN == CTN4)
7902 n2 -= 2;
7903 else
7904 n2 -= 1;
7905 break;
7906
7907 case CSLS:
7908 case CSTS:
7909 n2 = (int) e->N2 - 1;
7910 break;
7911
7912 case CSNS:
7913 n2 = (int) e->N2;
7914 break;
7915 }
7916
7917 sim_debug (DBG_CAC, & cpu_dev, "n2 %d\r\n", n2);
7918
7919 if (n2 < 1)
7920 doFault (FAULT_IPR, fst_ill_proc, "mvn adjusted n2<1");
7921
7922 decContext set;
7923 decContextDefaultDPS8(&set);
7924 set.traps=0;
7925
7926 decNumber _1;
7927
7928 EISloadInputBufferNumeric (cpup, 1);
7929
7930 decNumber *op1 = decBCD9ToNumber (e->inBuffer, n1, sc1, &_1);
7931
7932 if (e->sign == -1)
7933 op1->bits |= DECNEG;
7934 if (e->S1 == CSFL)
7935 op1->exponent = e->exponent;
7936 if (decNumberIsZero (op1))
7937 op1->exponent = 127;
7938
7939 if_sim_debug (DBG_CAC, & cpu_dev)
7940 {
7941 PRINTDEC ("mvn input (op1)", op1);
7942 }
7943
7944 bool Ovr = false, EOvr = false, Trunc = false;
7945
7946 uint8_t out [256];
7947 char * res = formatDecimal (out, & set, op1, n2, (int) e->S2, e->SF2, R,
7948 & Ovr, & Trunc);
7949
7950 sim_debug (DBG_CAC, & cpu_dev, "mvn res: '%s'\r\n", res);
7951
7952
7953
7954
7955 int pos = (int) dstCN;
7956
7957
7958 switch(e->S2)
7959 {
7960 case CSFL:
7961 case CSLS:
7962 switch(dstTN)
7963 {
7964 case CTN4:
7965
7966
7967
7968 if (e->P)
7969
7970 EISwrite49 (cpup, & e->ADDR2, & pos, (int) dstTN,
7971 (decNumberIsNegative (op1) &&
7972 ! decNumberIsZero(op1)) ? 015 : 013);
7973 else
7974
7975 EISwrite49 (cpup, & e->ADDR2, & pos, (int) dstTN,
7976 (decNumberIsNegative (op1) &&
7977 ! decNumberIsZero (op1)) ? 015 : 014);
7978 break;
7979 case CTN9:
7980 EISwrite49 (cpup, & e->ADDR2, & pos, (int) dstTN,
7981 (decNumberIsNegative (op1) &&
7982 ! decNumberIsZero (op1)) ? '-' : '+');
7983 break;
7984 }
7985 break;
7986
7987 case CSTS:
7988 case CSNS:
7989 break;
7990 }
7991
7992
7993 for (int i = 0 ; i < n2 ; i ++)
7994 switch (dstTN)
7995 {
7996 case CTN4:
7997 EISwrite49 (cpup, & e->ADDR2, & pos, (int) dstTN,
7998 (word9) (res[i] - '0'));
7999 break;
8000 case CTN9:
8001 EISwrite49 (cpup, & e->ADDR2, & pos, (int) dstTN, (word9) res[i]);
8002 break;
8003 }
8004
8005
8006 switch(e->S2)
8007 {
8008 case CSTS:
8009 switch(dstTN)
8010 {
8011 case CTN4:
8012
8013
8014
8015 if (e->P)
8016
8017 EISwrite49 (cpup, & e->ADDR2, & pos, (int) dstTN,
8018 (decNumberIsNegative (op1) &&
8019 ! decNumberIsZero(op1)) ? 015 : 013);
8020 else
8021
8022 EISwrite49 (cpup, & e->ADDR2, & pos, (int) dstTN,
8023 (decNumberIsNegative (op1) &&
8024 ! decNumberIsZero (op1)) ? 015 : 014);
8025 break;
8026
8027 case CTN9:
8028 EISwrite49 (cpup, & e->ADDR2, & pos, (int) dstTN,
8029 (decNumberIsNegative (op1) &&
8030 ! decNumberIsZero(op1)) ? '-' : '+');
8031 break;
8032 }
8033 break;
8034
8035 case CSFL:
8036
8037 switch(dstTN)
8038 {
8039 case CTN4:
8040 EISwrite49 (cpup, & e->ADDR2, & pos, (int) dstTN,
8041 (op1->exponent >> 4) & 0xf);
8042 EISwrite49 (cpup, & e->ADDR2, & pos, (int) dstTN,
8043 op1->exponent & 0xf);
8044 break;
8045 case CTN9:
8046 EISwrite49 (cpup, & e->ADDR2, & pos, (int) dstTN,
8047 op1->exponent & 0xff);
8048 break;
8049 }
8050 break;
8051
8052 case CSLS:
8053 case CSNS:
8054 break;
8055 }
8056
8057
8058 if (e->S2 == CSFL)
8059 {
8060 if (op1->exponent > 127)
8061 {
8062 SET_I_EOFL;
8063 EOvr = true;
8064 }
8065 if (op1->exponent < -128)
8066 {
8067 SET_I_EUFL;
8068 EOvr = true;
8069 }
8070 }
8071
8072 sim_debug (DBG_CAC, & cpu_dev, "is neg %o\r\n", decNumberIsNegative(op1));
8073 sim_debug (DBG_CAC, & cpu_dev, "is zero %o\r\n", decNumberIsZero(op1));
8074 sim_debug (DBG_CAC, & cpu_dev, "R %o\r\n", R);
8075 sim_debug (DBG_CAC, & cpu_dev, "Trunc %o\r\n", Trunc);
8076 sim_debug (DBG_CAC, & cpu_dev, "TRUNC %o\r\n", TST_I_TRUNC);
8077 sim_debug (DBG_CAC, & cpu_dev, "OMASK %o\r\n", TST_I_OMASK);
8078 sim_debug (DBG_CAC, & cpu_dev, "tstOVFfault %o\r\n", tstOVFfault (cpup));
8079 sim_debug (DBG_CAC, & cpu_dev, "T %o\r\n", T);
8080 sim_debug (DBG_CAC, & cpu_dev, "EOvr %o\r\n", EOvr);
8081 sim_debug (DBG_CAC, & cpu_dev, "Ovr %o\r\n", Ovr);
8082
8083 SC_I_NEG (decNumberIsNegative(op1) && !decNumberIsZero(op1));
8084
8085
8086 SC_I_ZERO (decNumberIsZero(op1));
8087
8088
8089
8090 SC_I_TRUNC (!R && Trunc);
8091
8092 cleanupOperandDescriptor (cpup, 1);
8093 cleanupOperandDescriptor (cpup, 2);
8094
8095 if (TST_I_TRUNC && T && tstOVFfault (cpup))
8096 doFault (FAULT_OFL, fst_zero, "mvn truncation(overflow) fault");
8097 if (EOvr && tstOVFfault (cpup))
8098 doFault (FAULT_OFL, fst_zero, "mvn over/underflow fault");
8099 if (Ovr)
8100 {
8101 SET_I_OFLOW;
8102 if (tstOVFfault (cpup))
8103 doFault (FAULT_OFL, fst_zero, "mvn overflow fault");
8104 }
8105 }
8106
8107 void csl (cpu_state_t * cpup)
8108 {
8109 EISstruct * e = & cpu.currentEISinstruction;
8110
8111
8112
8113
8114
8115
8116
8117
8118
8119
8120
8121
8122
8123
8124
8125
8126
8127
8128
8129
8130
8131
8132
8133
8134
8135
8136
8137
8138
8139
8140
8141
8142
8143
8144
8145
8146
8147
8148
8149
8150
8151
8152
8153
8154
8155
8156
8157
8158
8159
8160
8161
8162
8163
8164
8165
8166 fault_ipr_subtype_ mod_fault = 0;
8167
8168 #if !defined(EIS_SETUP)
8169 setupOperandDescriptor (cpup, 1, & mod_fault);
8170 setupOperandDescriptor (cpup, 2, & mod_fault);
8171 #endif
8172
8173 parseBitstringOperandDescriptor (cpup, 1, & mod_fault);
8174 parseBitstringOperandDescriptor (cpup, 2, & mod_fault);
8175
8176 L68_ (
8177
8178 if (mod_fault)
8179 doFault (FAULT_IPR,
8180 (_fault_subtype) {.fault_ipr_subtype=mod_fault},
8181 "Illegal modifier");
8182 )
8183
8184
8185 if (IWB_IRODD & 0360200000000)
8186 doFault (FAULT_IPR, (_fault_subtype) {.fault_ipr_subtype=FR_ILL_OP|mod_fault}, "csl 1-4,10 MBZ");
8187
8188 DPS8M_ (
8189
8190 if (mod_fault)
8191 doFault (FAULT_IPR,
8192 (_fault_subtype) {.fault_ipr_subtype=mod_fault},
8193 "Illegal modifier");
8194 )
8195
8196 e->ADDR1.cPos = (int) e->C1;
8197 e->ADDR2.cPos = (int) e->C2;
8198
8199 e->ADDR1.bPos = (int) e->B1;
8200 e->ADDR2.bPos = (int) e->B2;
8201
8202 bool F = getbits36_1 (cpu.cu.IWB, 0) != 0;
8203 bool T = getbits36_1 (cpu.cu.IWB, 9) != 0;
8204
8205 uint BOLR = getbits36_4 (cpu.cu.IWB, 5);
8206 bool B5 = !! (BOLR & 8);
8207 bool B6 = !! (BOLR & 4);
8208 bool B7 = !! (BOLR & 2);
8209 bool B8 = !! (BOLR & 1);
8210
8211 e->ADDR1.mode = eRWreadBit;
8212
8213 #if !defined(EIS_PTR)
8214 sim_debug (DBG_TRACEEXT, & cpu_dev,
8215 "CSL N1 %d N2 %d\r\n"
8216 "CSL C1 %d C2 %d B1 %d B2 %d F %o T %d\r\n"
8217 "CSL BOLR %u%u%u%u\r\n"
8218 "CSL op1 SNR %06o WORDNO %06o CHAR %d BITNO %d\r\n"
8219 "CSL op2 SNR %06o WORDNO %06o CHAR %d BITNO %d\r\n",
8220 e -> N1, e -> N2,
8221 e -> C1, e -> C2, e -> B1, e -> B2, F, T,
8222 B5, B6, B7, B8,
8223 e -> addr [0].SNR, e -> addr [0].address,
8224 e -> addr [0].cPos, e -> addr [0].bPos,
8225 e -> addr [1].SNR, e -> addr [1].address,
8226 e -> addr [1].cPos, e -> addr [1].bPos);
8227 #endif
8228
8229 bool bR = false;
8230
8231 PNL (L68_ (if (max (e->N1, e->N2) < 128)
8232 DU_CYCLE_FLEN_128;))
8233
8234 for( ; cpu.du.CHTALLY < min(e->N1, e->N2); cpu.du.CHTALLY += 1)
8235 {
8236 tandd_eis_sample (cpup, cpu.du.CHTALLY, 36);
8237 bool b1 = EISgetBitRWN(cpup, &e->ADDR1, true);
8238 e->ADDR2.mode = eRWreadBit;
8239 bool b2 = EISgetBitRWN(cpup, &e->ADDR2, true);
8240
8241 if (b1) if (b2) bR = B8; else bR = B7; else if (b2) bR = B6; else bR = B5;
8242
8243 if (bR)
8244 {
8245
8246 cpu.du.Z = 0;
8247 }
8248
8249
8250 e->ADDR2.bit = bR ? 1 : 0;
8251 e->ADDR2.mode = eRWwriteBit;
8252
8253
8254 EISgetBitRWN(cpup, &e->ADDR2, e->ADDR1.last_bit_posn == 35);
8255 }
8256
8257 if (e->N1 < e->N2)
8258 {
8259 for(; cpu.du.CHTALLY < e->N2; cpu.du.CHTALLY += 1)
8260 {
8261 tandd_eis_sample (cpup, cpu.du.CHTALLY, 36);
8262 bool b1 = F;
8263
8264 e->ADDR2.mode = eRWreadBit;
8265 bool b2 = EISgetBitRWN(cpup, &e->ADDR2, true);
8266
8267 if (b1) if (b2) bR = B8; else bR = B7; else if (b2) bR = B6; else bR = B5;
8268
8269 if (bR)
8270 {
8271
8272 cpu.du.Z = 0;
8273 }
8274
8275
8276 e->ADDR2.bit = bR ? 1 : 0;
8277 e->ADDR2.mode = eRWwriteBit;
8278
8279
8280 EISgetBitRWN(cpup, &e->ADDR2, e->ADDR1.last_bit_posn == 35);
8281 }
8282 }
8283
8284 EISWriteCache (cpup, &e->ADDR2);
8285
8286 cleanupOperandDescriptor (cpup, 1);
8287 cleanupOperandDescriptor (cpup, 2);
8288
8289 SC_I_ZERO (cpu.du.Z);
8290 if (e->N1 > e->N2)
8291 {
8292
8293
8294
8295
8296
8297
8298 SET_I_TRUNC;
8299 if (T && tstOVFfault (cpup))
8300 doFault(FAULT_OFL, fst_zero, "csl truncation fault");
8301 }
8302 else
8303 {
8304 CLR_I_TRUNC;
8305 }
8306 }
8307
8308
8309
8310
8311
8312
8313
8314
8315 static void getBitOffsets(int length, int initC, int initB, int *nWords, int *newC, int *newB)
8316 {
8317 if (length == 0)
8318 return;
8319
8320 int endBit = (length + 9 * initC + initB - 1) % 36;
8321
8322
8323 int numWords = (length + 9 * initC + initB + 35) / 36;
8324 int lastWordOffset = numWords - 1;
8325
8326 if (lastWordOffset > 0)
8327 *nWords = lastWordOffset;
8328 else
8329 *nWords = 0;
8330
8331 *newC = endBit / 9;
8332 *newB = endBit % 9;
8333 }
8334
8335 static bool EISgetBitRWNR (cpu_state_t * cpup, EISaddr * p, bool flush)
8336 {
8337 int baseCharPosn = (p -> cPos * 9);
8338 int baseBitPosn = baseCharPosn + p -> bPos;
8339 baseBitPosn -= (int) cpu.du.CHTALLY;
8340
8341 int bitPosn = baseBitPosn % 36;
8342 int woff = baseBitPosn / 36;
8343 while (bitPosn < 0)
8344 {
8345 bitPosn += 36;
8346 woff -= 1;
8347 }
8348
8349
8350
8351
8352
8353
8354
8355
8356
8357
8358 #if defined(EIS_PTR)
8359 long eisaddr_idx = EISADDR_IDX (p);
8360 if (eisaddr_idx < 0 || eisaddr_idx > 2) { sim_warn ("IDX1"); return }
8361 word18 saveAddr = cpu.du.Dk_PTR_W[eisaddr_idx];
8362 cpu.du.Dk_PTR_W[eisaddr_idx] += (word18) woff;
8363 cpu.du.Dk_PTR_W[eisaddr_idx] &= AMASK;
8364 #else
8365 word18 saveAddr = p -> address;
8366
8367
8368 p->address = (word18) (((word18s) p->address) + (word18s) woff);
8369 #endif
8370
8371 p -> data = EISRead (cpup, p);
8372
8373 if (p -> mode == eRWreadBit)
8374 {
8375 p -> bit = getbits36_1 (p -> data, (uint) bitPosn);
8376 }
8377 else if (p -> mode == eRWwriteBit)
8378 {
8379
8380 p -> data = setbits36_1 (p -> data, (uint) bitPosn, p -> bit);
8381
8382 EISWriteIdx (cpup, p, 0, p -> data, flush);
8383 }
8384
8385 p->last_bit_posn = bitPosn;
8386
8387 #if defined(EIS_PTR)
8388 cpu.du.Dk_PTR_W[eisaddr_idx] = saveAddr;
8389 #else
8390 p -> address = saveAddr;
8391 #endif
8392 return p -> bit;
8393 }
8394
8395 void csr (cpu_state_t * cpup)
8396 {
8397 EISstruct * e = & cpu.currentEISinstruction;
8398
8399
8400
8401
8402
8403
8404
8405
8406
8407
8408
8409
8410
8411
8412
8413
8414
8415
8416
8417
8418
8419
8420
8421
8422
8423
8424
8425
8426
8427
8428
8429
8430
8431
8432
8433
8434
8435
8436 fault_ipr_subtype_ mod_fault = 0;
8437
8438 #if !defined(EIS_SETUP)
8439 setupOperandDescriptor(cpup, 1, &mod_fault);
8440 setupOperandDescriptor(cpup, 2, &mod_fault);
8441 #endif
8442
8443 parseBitstringOperandDescriptor(cpup, 1, &mod_fault);
8444 parseBitstringOperandDescriptor(cpup, 2, &mod_fault);
8445
8446 L68_ (
8447
8448 if (mod_fault)
8449 doFault (FAULT_IPR,
8450 (_fault_subtype) {.fault_ipr_subtype=mod_fault},
8451 "Illegal modifier");
8452 )
8453
8454
8455 if (IWB_IRODD & 0360200000000)
8456 doFault (FAULT_IPR, (_fault_subtype) {.fault_ipr_subtype=FR_ILL_OP|mod_fault}, "csr 1-4,10 MBZ");
8457
8458 DPS8M_ (
8459
8460 if (mod_fault)
8461 doFault (FAULT_IPR,
8462 (_fault_subtype) {.fault_ipr_subtype=mod_fault},
8463 "Illegal modifier");
8464 )
8465
8466 e->ADDR1.cPos = (int) e->C1;
8467 e->ADDR2.cPos = (int) e->C2;
8468
8469 e->ADDR1.bPos = (int) e->B1;
8470 e->ADDR2.bPos = (int) e->B2;
8471
8472
8473 int numWords1=0, numWords2=0;
8474
8475 getBitOffsets((int) e->N1, (int) e->C1, (int) e->B1, &numWords1, &e->ADDR1.cPos, &e->ADDR1.bPos);
8476 PNL (cpu.du.D1_PTR_W += (word18) numWords1);
8477 PNL (cpu.du.D1_PTR_W &= AMASK);
8478 #if defined(EIS_PTR)
8479 cpu.du.D1_PTR_W += (word18) numWords1;
8480 cpu.du.D1_PTR_W &= AMASK;
8481 #else
8482 e->ADDR1.address += (word18) numWords1;
8483 #endif
8484
8485 sim_debug (DBG_TRACEEXT, & cpu_dev,
8486 "CSR N1 %d C1 %d B1 %d numWords1 %d cPos %d bPos %d\r\n",
8487 e->N1, e->C1, e->B1, numWords1, e->ADDR1.cPos, e->ADDR1.bPos);
8488 getBitOffsets((int) e->N2, (int) e->C2, (int) e->B2, &numWords2, &e->ADDR2.cPos, &e->ADDR2.bPos);
8489 sim_debug (DBG_TRACEEXT, & cpu_dev,
8490 "CSR N2 %d C2 %d B2 %d numWords2 %d cPos %d bPos %d\r\n",
8491 e->N2, e->C2, e->B2, numWords2, e->ADDR2.cPos, e->ADDR2.bPos);
8492 PNL (cpu.du.D2_PTR_W += (word18) numWords1);
8493 PNL (cpu.du.D2_PTR_W &= AMASK);
8494 #if defined(EIS_PTR)
8495 cpu.du.D2_PTR_W += (word18) numWords1;
8496 cpu.du.D2_PTR_W &= AMASK;
8497 #else
8498 e->ADDR2.address += (word18) numWords2;
8499 #endif
8500
8501 bool F = getbits36_1 (cpu.cu.IWB, 0) != 0;
8502 bool T = getbits36_1 (cpu.cu.IWB, 9) != 0;
8503
8504 uint BOLR = getbits36_4 (cpu.cu.IWB, 5);
8505 bool B5 = !! (BOLR & 8);
8506 bool B6 = !! (BOLR & 4);
8507 bool B7 = !! (BOLR & 2);
8508 bool B8 = !! (BOLR & 1);
8509
8510 e->ADDR1.mode = eRWreadBit;
8511
8512 CLR_I_TRUNC;
8513
8514 bool bR = false;
8515
8516 PNL (L68_ (if (max (e->N1, e->N2) < 128)
8517 DU_CYCLE_FLEN_128;))
8518
8519 for( ; cpu.du.CHTALLY < min(e->N1, e->N2); cpu.du.CHTALLY += 1)
8520 {
8521 tandd_eis_sample (cpup, cpu.du.CHTALLY, 36);
8522 bool b1 = EISgetBitRWNR(cpup, &e->ADDR1, true);
8523
8524 e->ADDR2.mode = eRWreadBit;
8525 bool b2 = EISgetBitRWNR(cpup, &e->ADDR2, true);
8526
8527 if (b1) if (b2) bR = B8; else bR = B7; else if (b2) bR = B6; else bR = B5;
8528
8529 if (bR)
8530 cpu.du.Z = 0;
8531
8532
8533 e->ADDR2.bit = bR ? 1 : 0;
8534 e->ADDR2.mode = eRWwriteBit;
8535
8536
8537 EISgetBitRWNR(cpup, &e->ADDR2, e->ADDR1.last_bit_posn == 0);
8538 }
8539
8540 if (e->N1 < e->N2)
8541 {
8542 for(; cpu.du.CHTALLY < e->N2; cpu.du.CHTALLY += 1)
8543 {
8544 tandd_eis_sample (cpup, cpu.du.CHTALLY, 36);
8545 bool b1 = F;
8546
8547 e->ADDR2.mode = eRWreadBit;
8548 bool b2 = EISgetBitRWNR(cpup, &e->ADDR2, true);
8549
8550 if (b1) if (b2) bR = B8; else bR = B7; else if (b2) bR = B6; else bR = B5;
8551
8552 if (bR)
8553 {
8554
8555 cpu.du.Z = 0;
8556 }
8557
8558
8559 e->ADDR2.bit = bR ? 1 : 0;
8560 e->ADDR2.mode = eRWwriteBit;
8561
8562
8563 EISgetBitRWNR(cpup, &e->ADDR2, e->ADDR1.last_bit_posn == 0);
8564 }
8565 }
8566
8567 EISWriteCache (cpup, &e->ADDR2);
8568
8569 cleanupOperandDescriptor (cpup, 1);
8570 cleanupOperandDescriptor (cpup, 2);
8571
8572 SC_I_ZERO (cpu.du.Z);
8573 if (e->N1 > e->N2)
8574 {
8575
8576
8577
8578
8579
8580
8581 SET_I_TRUNC;
8582 if (T && tstOVFfault (cpup))
8583 doFault(FAULT_OFL, fst_zero, "csr truncation fault");
8584 }
8585 else
8586 {
8587 CLR_I_TRUNC;
8588 }
8589 }
8590
8591 void sztl (cpu_state_t * cpup)
8592 {
8593
8594
8595
8596
8597 EISstruct * e = & cpu.currentEISinstruction;
8598
8599
8600
8601
8602
8603
8604
8605
8606
8607
8608
8609
8610
8611
8612
8613
8614
8615
8616
8617
8618
8619
8620
8621
8622
8623
8624
8625
8626
8627
8628
8629
8630
8631
8632
8633
8634
8635
8636
8637
8638
8639
8640
8641
8642
8643
8644
8645
8646
8647
8648
8649
8650
8651
8652
8653
8654 fault_ipr_subtype_ mod_fault = 0;
8655
8656 #if !defined(EIS_SETUP)
8657 setupOperandDescriptor (cpup, 1, &mod_fault);
8658 setupOperandDescriptor (cpup, 2, &mod_fault);
8659 #endif
8660
8661 parseBitstringOperandDescriptor (cpup, 1, &mod_fault);
8662 parseBitstringOperandDescriptor (cpup, 2, &mod_fault);
8663
8664 L68_ (
8665
8666 if (mod_fault)
8667 doFault (FAULT_IPR,
8668 (_fault_subtype) {.fault_ipr_subtype=mod_fault},
8669 "Illegal modifier");
8670 )
8671
8672
8673 if (IWB_IRODD & 0360200000000)
8674 doFault (FAULT_IPR, (_fault_subtype) {.fault_ipr_subtype=FR_ILL_OP|mod_fault}, "csl 1-4,10 MBZ");
8675
8676 DPS8M_ (
8677
8678 if (mod_fault)
8679 doFault (FAULT_IPR,
8680 (_fault_subtype) {.fault_ipr_subtype=mod_fault},
8681 "Illegal modifier");
8682 )
8683
8684 e->ADDR1.cPos = (int) e->C1;
8685 e->ADDR2.cPos = (int) e->C2;
8686
8687 e->ADDR1.bPos = (int) e->B1;
8688 e->ADDR2.bPos = (int) e->B2;
8689
8690 bool F = getbits36_1 (cpu.cu.IWB, 0) != 0;
8691 bool T = getbits36_1 (cpu.cu.IWB, 9) != 0;
8692
8693 uint BOLR = getbits36_4 (cpu.cu.IWB, 5);
8694 bool B5 = !! (BOLR & 8);
8695 bool B6 = !! (BOLR & 4);
8696 bool B7 = !! (BOLR & 2);
8697 bool B8 = !! (BOLR & 1);
8698
8699 e->ADDR1.mode = eRWreadBit;
8700 e->ADDR2.mode = eRWreadBit;
8701
8702 #if !defined(EIS_PTR)
8703 sim_debug (DBG_TRACEEXT, & cpu_dev,
8704 "SZTL N1 %d N2 %d\r\n"
8705 "SZTL C1 %d C2 %d B1 %d B2 %d F %o T %d\r\n"
8706 "SZTL BOLR %u%u%u%u\r\n"
8707 "SZTL op1 SNR %06o WORDNO %06o CHAR %d BITNO %d\r\n"
8708 "SZTL op2 SNR %06o WORDNO %06o CHAR %d BITNO %d\r\n",
8709 e -> N1, e -> N2,
8710 e -> C1, e -> C2, e -> B1, e -> B2, F, T,
8711 B5, B6, B7, B8,
8712 e -> addr [0].SNR, e -> addr [0].address,
8713 e -> addr [0].cPos, e -> addr [0].bPos,
8714 e -> addr [1].SNR, e -> addr [1].address,
8715 e -> addr [1].cPos, e -> addr [1].bPos);
8716 #endif
8717
8718 bool bR = false;
8719
8720 PNL (L68_ (if (max (e->N1, e->N2) < 128)
8721 DU_CYCLE_FLEN_128;))
8722
8723 for( ; cpu.du.CHTALLY < min (e->N1, e->N2); cpu.du.CHTALLY += 1)
8724 {
8725 tandd_eis_sample (cpup, cpu.du.CHTALLY, 36);
8726 bool b1 = EISgetBitRWN (cpup, & e->ADDR1, true);
8727 bool b2 = EISgetBitRWN (cpup, & e->ADDR2, true);
8728
8729 if (b1) if (b2) bR = B8; else bR = B7; else if (b2) bR = B6; else bR = B5;
8730
8731 if (bR)
8732 {
8733
8734 cpu.du.Z = 0;
8735 break;
8736 }
8737 }
8738
8739 if (e->N1 < e->N2)
8740 {
8741 for (; cpu.du.CHTALLY < e->N2; cpu.du.CHTALLY += 1)
8742 {
8743 tandd_eis_sample (cpup, cpu.du.CHTALLY, 36);
8744 bool b1 = F;
8745 bool b2 = EISgetBitRWN (cpup, & e->ADDR2, true);
8746
8747 if (b1) if (b2) bR = B8; else bR = B7; else if (b2) bR = B6; else bR = B5;
8748
8749 if (bR)
8750 {
8751
8752 cpu.du.Z = 0;
8753 break;
8754 }
8755 }
8756 }
8757
8758 cleanupOperandDescriptor (cpup, 1);
8759 cleanupOperandDescriptor (cpup, 2);
8760
8761 SC_I_ZERO (cpu.du.Z);
8762 if (e->N1 > e->N2)
8763 {
8764
8765
8766
8767
8768
8769
8770 SET_I_TRUNC;
8771 if (T && tstOVFfault (cpup))
8772 doFault(FAULT_OFL, fst_zero, "csl truncation fault");
8773 }
8774 else
8775 {
8776 CLR_I_TRUNC;
8777 }
8778 }
8779
8780 void sztr (cpu_state_t * cpup)
8781 {
8782
8783
8784
8785
8786 EISstruct * e = & cpu.currentEISinstruction;
8787
8788
8789
8790
8791
8792
8793
8794
8795
8796
8797
8798
8799
8800
8801
8802
8803
8804
8805
8806
8807
8808
8809
8810
8811
8812
8813
8814
8815
8816
8817
8818
8819
8820
8821
8822
8823
8824
8825 fault_ipr_subtype_ mod_fault = 0;
8826
8827 #if !defined(EIS_SETUP)
8828 setupOperandDescriptor(cpup, 1, &mod_fault);
8829 setupOperandDescriptor(cpup, 2, &mod_fault);
8830 #endif
8831
8832 parseBitstringOperandDescriptor(cpup, 1, &mod_fault);
8833 parseBitstringOperandDescriptor(cpup, 2, &mod_fault);
8834
8835 L68_ (
8836
8837 if (mod_fault)
8838 doFault (FAULT_IPR,
8839 (_fault_subtype) {.fault_ipr_subtype=mod_fault},
8840 "Illegal modifier");
8841 )
8842
8843
8844 if (IWB_IRODD & 0360200000000)
8845 doFault (FAULT_IPR, (_fault_subtype) {.fault_ipr_subtype=FR_ILL_OP|mod_fault}, "csr 1-4,10 MBZ");
8846
8847 DPS8M_ (
8848
8849 if (mod_fault)
8850 doFault (FAULT_IPR,
8851 (_fault_subtype) {.fault_ipr_subtype=mod_fault},
8852 "Illegal modifier");
8853 )
8854
8855 e->ADDR1.cPos = (int) e->C1;
8856 e->ADDR2.cPos = (int) e->C2;
8857
8858 e->ADDR1.bPos = (int) e->B1;
8859 e->ADDR2.bPos = (int) e->B2;
8860
8861
8862 int numWords1=0, numWords2=0;
8863
8864 getBitOffsets((int) e->N1, (int) e->C1, (int) e->B1, &numWords1, &e->ADDR1.cPos, &e->ADDR1.bPos);
8865 PNL (cpu.du.D1_PTR_W += (word18) numWords1);
8866 PNL (cpu.du.D1_PTR_W &= AMASK);
8867 #if defined(EIS_PTR)
8868 cpu.du.D1_PTR_W += (word18) numWords1;
8869 cpu.du.D1_PTR_W &= AMASK;
8870 #else
8871 e->ADDR1.address += (word18) numWords1;
8872 #endif
8873
8874 sim_debug (DBG_TRACEEXT, & cpu_dev,
8875 "CSR N1 %d C1 %d B1 %d numWords1 %d cPos %d bPos %d\r\n",
8876 e->N1, e->C1, e->B1, numWords1, e->ADDR1.cPos, e->ADDR1.bPos);
8877 getBitOffsets((int) e->N2, (int) e->C2, (int) e->B2, &numWords2, &e->ADDR2.cPos, &e->ADDR2.bPos);
8878 sim_debug (DBG_TRACEEXT, & cpu_dev,
8879 "CSR N2 %d C2 %d B2 %d numWords2 %d cPos %d bPos %d\r\n",
8880 e->N2, e->C2, e->B2, numWords2, e->ADDR2.cPos, e->ADDR2.bPos);
8881 PNL (cpu.du.D2_PTR_W += (word18) numWords1);
8882 PNL (cpu.du.D2_PTR_W &= AMASK);
8883 #if defined(EIS_PTR)
8884 cpu.du.D2_PTR_W += (word18) numWords1;
8885 cpu.du.D2_PTR_W &= AMASK;
8886 #else
8887 e->ADDR2.address += (word18) numWords2;
8888 #endif
8889
8890 bool F = getbits36_1 (cpu.cu.IWB, 0) != 0;
8891 bool T = getbits36_1 (cpu.cu.IWB, 9) != 0;
8892
8893 uint BOLR = getbits36_4 (cpu.cu.IWB, 5);
8894 bool B5 = !! (BOLR & 8);
8895 bool B6 = !! (BOLR & 4);
8896 bool B7 = !! (BOLR & 2);
8897 bool B8 = !! (BOLR & 1);
8898
8899 e->ADDR1.mode = eRWreadBit;
8900
8901 CLR_I_TRUNC;
8902
8903 bool bR = false;
8904
8905 PNL (L68_ (if (max (e->N1, e->N2) < 128)
8906 DU_CYCLE_FLEN_128;))
8907
8908 for( ; cpu.du.CHTALLY < min(e->N1, e->N2); cpu.du.CHTALLY += 1)
8909 {
8910 tandd_eis_sample (cpup, cpu.du.CHTALLY, 36);
8911 bool b1 = EISgetBitRWNR(cpup, &e->ADDR1, true);
8912
8913 e->ADDR2.mode = eRWreadBit;
8914 bool b2 = EISgetBitRWNR(cpup, &e->ADDR2, true);
8915
8916 if (b1) if (b2) bR = B8; else bR = B7; else if (b2) bR = B6; else bR = B5;
8917
8918 if (bR)
8919 {
8920 cpu.du.Z = 0;
8921 break;
8922 }
8923
8924 }
8925
8926 if (e->N1 < e->N2)
8927 {
8928 for(; cpu.du.CHTALLY < e->N2; cpu.du.CHTALLY += 1)
8929 {
8930 tandd_eis_sample (cpup, cpu.du.CHTALLY, 36);
8931 bool b1 = F;
8932
8933 e->ADDR2.mode = eRWreadBit;
8934 bool b2 = EISgetBitRWNR(cpup, &e->ADDR2, true);
8935
8936 if (b1) if (b2) bR = B8; else bR = B7; else if (b2) bR = B6; else bR = B5;
8937
8938 if (bR)
8939 {
8940
8941 cpu.du.Z = 0;
8942 break;
8943 }
8944
8945 }
8946 }
8947
8948 cleanupOperandDescriptor (cpup, 1);
8949 cleanupOperandDescriptor (cpup, 2);
8950
8951 SC_I_ZERO (cpu.du.Z);
8952 if (e->N1 > e->N2)
8953 {
8954
8955
8956
8957
8958
8959
8960 SET_I_TRUNC;
8961 if (T && tstOVFfault (cpup))
8962 doFault(FAULT_OFL, fst_zero, "csr truncation fault");
8963 }
8964 else
8965 {
8966 CLR_I_TRUNC;
8967 }
8968 }
8969
8970
8971
8972
8973
8974
8975
8976
8977
8978
8979 static bool EISgetBit(cpu_state_t * cpup, EISaddr *p, int *cpos, int *bpos)
8980 {
8981 #if defined(EIS_PTR)
8982 long eisaddr_idx = EISADDR_IDX (p);
8983 if (eisaddr_idx < 0 || eisaddr_idx > 2) { sim_warn ("IDX1"); return }
8984 #endif
8985
8986 if (!p)
8987 {
8988
8989 return 0;
8990 }
8991
8992 if (*bpos > 8)
8993 {
8994 *bpos = 0;
8995 *cpos += 1;
8996 if (*cpos > 3)
8997 {
8998 *cpos = 0;
8999 #if defined(EIS_PTR)
9000 cpu.du.Dk_PTR_W[eisaddr_idx] += 1;
9001 cpu.du.Dk_PTR_W[eisaddr_idx] &= AMASK;
9002 #else
9003 p->address += 1;
9004 p->address &= AMASK;
9005 #endif
9006 }
9007 }
9008
9009 p->data = EISRead(cpup, p);
9010
9011 int charPosn = *cpos * 9;
9012 int bitPosn = charPosn + *bpos;
9013 bool b = getbits36_1 (p->data, (uint) bitPosn) != 0;
9014
9015 *bpos += 1;
9016
9017 return b;
9018 }
9019
9020 void cmpb (cpu_state_t * cpup)
9021 {
9022 EISstruct * e = & cpu.currentEISinstruction;
9023
9024
9025
9026
9027
9028
9029
9030
9031
9032
9033
9034
9035 fault_ipr_subtype_ mod_fault = 0;
9036
9037 #if !defined(EIS_SETUP)
9038 setupOperandDescriptor(cpup, 1, &mod_fault);
9039 setupOperandDescriptor(cpup, 2, &mod_fault);
9040 #endif
9041
9042 parseBitstringOperandDescriptor(cpup, 1, &mod_fault);
9043 parseBitstringOperandDescriptor(cpup, 2, &mod_fault);
9044
9045 L68_ (
9046
9047 if (mod_fault)
9048 {
9049 doFault (FAULT_IPR,
9050 (_fault_subtype) {.fault_ipr_subtype=mod_fault},
9051 "Illegal modifier");
9052 }
9053 )
9054
9055
9056 if (IWB_IRODD & 0377200000000)
9057 doFault (FAULT_IPR, (_fault_subtype) {.fault_ipr_subtype=FR_ILL_OP|mod_fault}, "cmpb 1-8,10 MBZ");
9058
9059 DPS8M_ (
9060
9061 if (mod_fault)
9062 {
9063 doFault (FAULT_IPR,
9064 (_fault_subtype) {.fault_ipr_subtype=mod_fault},
9065 "Illegal modifier");
9066 }
9067 )
9068
9069 int charPosn1 = (int) e->C1;
9070 int charPosn2 = (int) e->C2;
9071
9072 int bitPosn1 = (int) e->B1;
9073 int bitPosn2 = (int) e->B2;
9074
9075 bool F = getbits36_1 (cpu.cu.IWB, 0) != 0;
9076
9077 SET_I_ZERO;
9078 SET_I_CARRY;
9079
9080 sim_debug (DBG_TRACEEXT, & cpu_dev, "cmpb N1 %d N2 %d\r\n", e -> N1, e -> N2);
9081
9082
9083
9084
9085
9086
9087
9088
9089
9090
9091
9092
9093
9094
9095
9096
9097
9098 PNL (L68_ (if (max (e->N1, e->N2) < 128)
9099 DU_CYCLE_FLEN_128;))
9100
9101 uint i = 0;
9102
9103
9104 if (cpu.tweaks.tandd_mode)
9105 for ( ; i < cpu.du.CHTALLY; i ++)
9106 {
9107 if (i < e->N1)
9108 (void) EISgetBit (cpup, &e->ADDR1, &charPosn1, &bitPosn1);
9109 if (i < e->N2)
9110 (void) EISgetBit (cpup, &e->ADDR2, &charPosn2, &bitPosn2);
9111 }
9112 for( ; i < min(e->N1, e->N2) ; i += 1)
9113 {
9114 tandd_eis_sample (cpup, i, 36);
9115 bool b1 = EISgetBit (cpup, &e->ADDR1, &charPosn1, &bitPosn1);
9116 bool b2 = EISgetBit (cpup, &e->ADDR2, &charPosn2, &bitPosn2);
9117
9118 sim_debug (DBG_TRACEEXT, & cpu_dev, "cmpb(min(e->N1, e->N2)) i %d b1 %d b2 %d\r\n", i, b1, b2);
9119 if (b1 != b2)
9120 {
9121 CLR_I_ZERO;
9122 if (!b1 && b2)
9123 CLR_I_CARRY;
9124
9125 cleanupOperandDescriptor (cpup, 1);
9126 cleanupOperandDescriptor (cpup, 2);
9127
9128 return;
9129 }
9130
9131 }
9132 if (e->N1 < e->N2)
9133 {
9134 for(; i < e->N2 ; i += 1)
9135 {
9136 tandd_eis_sample (cpup, i, 36);
9137 bool b1 = F;
9138 bool b2 = EISgetBit(cpup, &e->ADDR2, &charPosn2, &bitPosn2);
9139 sim_debug (DBG_TRACEEXT, & cpu_dev, "cmpb(e->N1 < e->N2) i %d b1fill %d b2 %d\r\n", i, b1, b2);
9140
9141 if (b1 != b2)
9142 {
9143 CLR_I_ZERO;
9144 if (!b1 && b2)
9145 CLR_I_CARRY;
9146
9147 cleanupOperandDescriptor (cpup, 1);
9148 cleanupOperandDescriptor (cpup, 2);
9149
9150 return;
9151 }
9152 }
9153 } else if (e->N1 > e->N2)
9154 {
9155 for(; i < e->N1 ; i += 1)
9156 {
9157 tandd_eis_sample (cpup, i, 36);
9158 bool b1 = EISgetBit(cpup, &e->ADDR1, &charPosn1, &bitPosn1);
9159 bool b2 = F;
9160 sim_debug (DBG_TRACEEXT, & cpu_dev, "cmpb(e->N1 > e->N2) i %d b1 %d b2fill %d\r\n", i, b1, b2);
9161
9162 if (b1 != b2)
9163 {
9164 CLR_I_ZERO;
9165 if (!b1 && b2)
9166 CLR_I_CARRY;
9167
9168 cleanupOperandDescriptor (cpup, 1);
9169 cleanupOperandDescriptor (cpup, 2);
9170
9171 return;
9172 }
9173 }
9174 }
9175 cleanupOperandDescriptor (cpup, 1);
9176 cleanupOperandDescriptor (cpup, 2);
9177 }
9178
9179
9180
9181
9182
9183
9184
9185
9186
9187
9188
9189
9190
9191
9192
9193
9194
9195
9196
9197
9198
9199
9200
9201
9202
9203
9204
9205
9206
9207
9208
9209
9210
9211
9212
9213
9214
9215
9216
9217
9218
9219
9220
9221
9222
9223
9224
9225
9226
9227
9228
9229
9230
9231
9232
9233
9234
9235
9236
9237
9238
9239
9240
9241
9242
9243
9244
9245
9246
9247
9248
9249
9250
9251
9252
9253
9254
9255
9256
9257
9258
9259
9260
9261
9262
9263
9264
9265
9266
9267
9268
9269
9270
9271
9272
9273
9274
9275
9276
9277
9278
9279
9280
9281
9282
9283
9284
9285
9286
9287
9288
9289
9290
9291
9292
9293
9294
9295
9296
9297
9298
9299
9300
9301
9302
9303
9304
9305
9306
9307
9308
9309
9310
9311
9312
9313
9314
9315
9316
9317
9318
9319
9320
9321
9322
9323
9324
9325
9326
9327
9328
9329
9330
9331
9332
9333
9334
9335
9336
9337
9338
9339
9340
9341
9342
9343
9344
9345
9346
9347
9348
9349
9350
9351
9352
9353
9354
9355
9356
9357
9358
9359
9360
9361
9362
9363
9364
9365
9366
9367
9368
9369
9370
9371
9372
9373
9374
9375
9376
9377
9378
9379
9380
9381
9382
9383
9384
9385
9386
9387
9388
9389
9390
9391
9392
9393
9394
9395
9396
9397
9398
9399
9400
9401
9402
9403 static bool sign9n(word72 n128, int N)
9404 {
9405
9406
9407
9408
9409
9410
9411
9412 if (N < 1 || N > 8)
9413 return false;
9414
9415 #if defined(NEED_128)
9416 word72 sgnmask = lshift_128 (construct_128 (0, 1), (uint) (N * 9 - 1));
9417 return isnonzero_128 (and_128 (sgnmask, n128));
9418 #else
9419 word72 sgnmask = (word72)1 << ((N * 9) - 1);
9420
9421 return (bool)(sgnmask & n128);
9422 #endif
9423 }
9424
9425
9426
9427
9428 static word72s signExt9(word72 n128, int N)
9429 {
9430
9431
9432
9433
9434
9435 int bits = (N * 9) - 1;
9436 if (sign9n(n128, N))
9437 {
9438 #if defined(NEED_128)
9439 uint128 extBits = lshift_128 (construct_128 (MASK64, MASK64), (uint) bits);
9440 uint128 or = or_128 (n128, extBits);
9441 return cast_s128 (or);
9442 #else
9443 uint128 extBits = ((uint128)-1 << bits);
9444 return (word72s) (n128 | extBits);
9445 #endif
9446 }
9447 #if defined(NEED_128)
9448 uint128 zeroBits = complement_128 (lshift_128 (construct_128 (MASK64, MASK64), (uint) bits));
9449 uint128 and = and_128 (n128, zeroBits);
9450 return cast_s128 (and);
9451 #else
9452 uint128 zeroBits = ~((uint128)-1 << bits);
9453 return (word72s) (n128 & zeroBits);
9454 #endif
9455 }
9456
9457
9458
9459
9460
9461 static void load9x(cpu_state_t * cpup, int n, EISaddr *addr, int pos)
9462 {
9463 EISstruct * e = & cpu.currentEISinstruction;
9464 #if defined(NEED_128)
9465 word72 x = construct_128 (0, 0);
9466 #else
9467 word72 x = 0;
9468 #endif
9469 #if defined(EIS_PTR)
9470 long eisaddr_idx = EISADDR_IDX (addr);
9471 if (eisaddr_idx < 0 || eisaddr_idx > 2) { sim_warn ("IDX1"); return }
9472 #endif
9473
9474 word36 data = EISRead(cpup, addr);
9475
9476 int m = n;
9477 while (m)
9478 {
9479 #if defined(NEED_128)
9480 x = lshift_128 (x, 9);
9481 #else
9482 x <<= 9;
9483 #endif
9484
9485 if (pos > 3)
9486 {
9487 pos = 0;
9488 #if EIS_PTR
9489 cpu.du.Dk_PTR_W[eisaddr_idx] = (cpu.du.Dk_PTR_W[eisaddr_idx] + 1) & AMASK;
9490 #else
9491 addr->address = (addr->address + 1) & AMASK;
9492 #endif
9493 data = EISRead(cpup, addr);
9494 }
9495
9496 #if defined(NEED_128)
9497 x = or_128 (x, construct_128 (0, GETBYTE (data, pos)));
9498 #else
9499 x |= GETBYTE(data, pos);
9500 #endif
9501
9502 pos += 1;
9503
9504 m -= 1;
9505 }
9506 e->x = signExt9(x, n);
9507 }
9508
9509
9510
9511
9512
9513
9514
9515
9516
9517
9518
9519
9520
9521
9522
9523
9524
9525
9526
9527
9528
9529
9530
9531
9532
9533
9534
9535
9536
9537
9538
9539
9540
9541
9542
9543
9544
9545
9546
9547
9548
9549
9550
9551
9552
9553
9554
9555
9556
9557
9558
9559
9560
9561
9562
9563
9564
9565
9566
9567
9568
9569
9570
9571
9572
9573
9574
9575
9576
9577
9578
9579
9580
9581
9582
9583
9584
9585
9586
9587
9588
9589
9590
9591
9592
9593
9594
9595
9596
9597
9598
9599
9600
9601
9602
9603
9604
9605
9606
9607
9608
9609
9610
9611
9612
9613
9614
9615
9616
9617
9618
9619
9620
9621
9622
9623
9624
9625
9626
9627
9628
9629 void btd (cpu_state_t * cpup)
9630 {
9631 EISstruct * e = & cpu.currentEISinstruction;
9632
9633
9634
9635
9636
9637
9638
9639
9640
9641
9642
9643
9644
9645
9646
9647
9648
9649
9650
9651
9652
9653
9654
9655
9656
9657
9658
9659
9660
9661
9662
9663
9664
9665
9666
9667
9668
9669
9670
9671
9672
9673
9674
9675
9676
9677
9678
9679
9680
9681
9682
9683
9684
9685
9686 fault_ipr_subtype_ mod_fault = 0;
9687
9688 #if !defined(EIS_SETUP)
9689 setupOperandDescriptor(cpup, 1, &mod_fault);
9690 setupOperandDescriptor(cpup, 2, &mod_fault);
9691 #endif
9692
9693 parseNumericOperandDescriptor(cpup, 1, &mod_fault);
9694 parseNumericOperandDescriptor(cpup, 2, &mod_fault);
9695
9696 L68_ (
9697
9698 if (mod_fault)
9699 {
9700 doFault (FAULT_IPR,
9701 (_fault_subtype) {.fault_ipr_subtype=mod_fault},
9702 "Illegal modifier");
9703 }
9704 )
9705
9706
9707 if (IWB_IRODD & 0377600000000)
9708 {
9709
9710 doFault (FAULT_IPR, (_fault_subtype) {.fault_ipr_subtype=FR_ILL_OP|mod_fault}, "btd 0-8 MBZ");
9711 }
9712
9713
9714 if (!(e->MF[0] & MFkID) && e -> op [0] & 0000000077700)
9715 doFault (FAULT_IPR, (_fault_subtype) {.fault_ipr_subtype=FR_ILL_PROC|mod_fault}, "btd op1 21-29 MBZ");
9716
9717
9718 if (!(e->MF[1] & MFkID) && e -> op [1] & 0000000007700)
9719 doFault (FAULT_IPR, (_fault_subtype) {.fault_ipr_subtype=FR_ILL_PROC|mod_fault}, "btd op2 24-29 MBZ");
9720
9721 if (e->S[1] == 0)
9722 doFault (FAULT_IPR, (_fault_subtype) {.fault_ipr_subtype=FR_ILL_PROC|mod_fault}, "btd op2 S=0");
9723
9724 DPS8M_ (
9725
9726 if (mod_fault)
9727 {
9728 doFault (FAULT_IPR,
9729 (_fault_subtype) {.fault_ipr_subtype=mod_fault},
9730 "Illegal modifier");
9731 }
9732 )
9733
9734 e->P = getbits36_1 (cpu.cu.IWB, 0) != 0;
9735
9736 if (e->N1 == 0 || e->N1 > 8)
9737 doFault(FAULT_IPR, fst_ill_proc, "btd(1): N1 == 0 || N1 > 8");
9738
9739 uint dstTN = e->TN2;
9740 uint dstCN = e->CN2;
9741
9742 int n2 = 0;
9743
9744 switch(e->S2)
9745 {
9746 case CSLS:
9747 case CSTS:
9748 n2 = (int) e->N2 - 1;
9749 break;
9750
9751 case CSNS:
9752 n2 = (int) e->N2;
9753 break;
9754 }
9755
9756 sim_debug (DBG_CAC, & cpu_dev,
9757 "n2 %d\r\n",
9758 n2);
9759
9760 if (n2 < 1)
9761 doFault (FAULT_IPR, fst_ill_proc, "btd adjusted n2<1");
9762
9763 decContext set;
9764 decContextDefaultDPS8(&set);
9765 set.traps=0;
9766
9767 load9x(cpup, (int) e->N1, &e->ADDR1, (int) e->CN1);
9768
9769
9770 e->sign = 1;
9771 #if defined(NEED_128)
9772 word72 x = cast_128 (e->x);
9773 if (islt_s128 (e->x, construct_s128 (0, 0)))
9774 {
9775 e->sign = -1;
9776 x = and_128 (negate_128 (x), MASK72);
9777
9778 }
9779
9780
9781 char tmp[32];
9782 tmp[31] = 0;
9783 int i;
9784 for (i=30;i>=0;i--) {
9785
9786
9787 uint16_t r;
9788 x = divide_128_16 (x, 10, & r);
9789 tmp[i] = (char) r + '0';
9790 if (iszero_128 (x))
9791 break;
9792 }
9793 #else
9794 word72 x = (word72)e->x;
9795 if (e->x < 0) {
9796 e->sign = -1;
9797
9798
9799 x = ((word72) (- (word72s) x)) & MASK72;
9800 }
9801
9802
9803 char tmp[32];
9804 tmp[31] = 0;
9805 int i;
9806 for (i=30;i>=0;i--) {
9807 tmp[i] = x%10 + '0';
9808 x /= 10;
9809 if (x == 0)
9810 break;
9811 }
9812 #endif
9813
9814 decNumber _1;
9815 decNumber *op1 = decNumberFromString(&_1, tmp+i, &set);
9816 if (e->sign == -1)
9817 op1->bits |= DECNEG;
9818
9819 bool Ovr = false, Trunc = false;
9820
9821 uint8_t out [256];
9822 char * res = formatDecimal (out, &set, op1, n2, (int) e->S2, e->SF2, 0, &Ovr, &Trunc);
9823
9824
9825
9826
9827 int pos = (int) dstCN;
9828
9829
9830 switch(e->S2)
9831 {
9832 case CSLS:
9833 switch(dstTN)
9834 {
9835 case CTN4:
9836 if (e->P)
9837
9838
9839 EISwrite49(cpup, &e->ADDR2, &pos, (int) dstTN,
9840 (decNumberIsNegative(op1) && !decNumberIsZero(op1)) ? 015 : 013);
9841 else
9842 EISwrite49(cpup, &e->ADDR2, &pos, (int) dstTN,
9843 (decNumberIsNegative(op1) && !decNumberIsZero(op1)) ? 015 : 014);
9844 break;
9845 case CTN9:
9846 EISwrite49(cpup, &e->ADDR2, &pos, (int) dstTN,
9847 (decNumberIsNegative(op1) && !decNumberIsZero(op1)) ? '-' : '+');
9848 break;
9849 }
9850 break;
9851
9852 case CSTS:
9853 case CSNS:
9854 break;
9855 }
9856
9857
9858 for(int i = 0 ; i < n2 ; i++)
9859 switch(dstTN)
9860 {
9861 case CTN4:
9862 EISwrite49(cpup, &e->ADDR2, &pos, (int) dstTN, (word9) (res[i] - '0'));
9863 break;
9864 case CTN9:
9865 EISwrite49(cpup, &e->ADDR2, &pos, (int) dstTN, (word9) res[i]);
9866 break;
9867 }
9868
9869
9870 switch(e->S2)
9871 {
9872 case CSTS:
9873 switch(dstTN)
9874 {
9875 case CTN4:
9876 if (e->P)
9877
9878
9879 EISwrite49(cpup, &e->ADDR2, &pos, (int) dstTN,
9880 (decNumberIsNegative(op1) && !decNumberIsZero(op1)) ? 015 : 013);
9881 else
9882 EISwrite49(cpup, &e->ADDR2, &pos, (int) dstTN,
9883 (decNumberIsNegative(op1) && !decNumberIsZero(op1)) ? 015 : 014);
9884 break;
9885
9886 case CTN9:
9887 EISwrite49(cpup, &e->ADDR2, &pos, (int) dstTN,
9888 (decNumberIsNegative(op1) && !decNumberIsZero(op1)) ? '-' : '+');
9889 break;
9890 }
9891 break;
9892
9893 case CSLS:
9894 case CSNS:
9895 break;
9896 }
9897
9898 SC_I_NEG (decNumberIsNegative(op1) && !decNumberIsZero(op1));
9899 SC_I_ZERO (decNumberIsZero(op1));
9900
9901 cleanupOperandDescriptor (cpup, 1);
9902 cleanupOperandDescriptor (cpup, 2);
9903
9904 if (Ovr)
9905 {
9906 SET_I_OFLOW;
9907 if (tstOVFfault (cpup))
9908 doFault(FAULT_OFL, fst_zero, "btd overflow fault");
9909 }
9910 }
9911
9912
9913
9914
9915
9916
9917
9918
9919
9920
9921
9922
9923
9924
9925
9926
9927
9928
9929
9930
9931
9932
9933
9934
9935
9936
9937
9938
9939
9940
9941
9942
9943
9944
9945
9946
9947
9948
9949
9950
9951
9952
9953
9954
9955
9956
9957
9958
9959
9960
9961
9962
9963
9964
9965
9966
9967
9968
9969
9970
9971
9972
9973
9974
9975
9976
9977
9978
9979
9980
9981
9982
9983
9984
9985
9986
9987
9988
9989
9990
9991
9992
9993
9994
9995
9996
9997
9998
9999
10000
10001
10002
10003
10004
10005
10006
10007
10008
10009
10010
10011
10012
10013
10014
10015
10016
10017
10018
10019
10020
10021
10022
10023
10024
10025
10026
10027
10028
10029
10030
10031
10032
10033
10034
10035
10036
10037
10038
10039
10040
10041
10042
10043
10044
10045
10046
10047
10048
10049
10050
10051
10052
10053
10054
10055
10056
10057
10058
10059
10060
10061
10062
10063
10064
10065
10066
10067
10068
10069
10070
10071
10072
10073
10074
10075
10076
10077
10078
10079
10080
10081
10082
10083
10084
10085
10086
10087
10088
10089
10090
10091
10092
10093
10094
10095
10096
10097
10098
10099
10100
10101
10102
10103
10104
10105
10106
10107
10108
10109
10110
10111
10112
10113
10114
10115
10116
10117
10118 void dtb (cpu_state_t * cpup)
10119 {
10120 EISstruct * e = & cpu.currentEISinstruction;
10121
10122 fault_ipr_subtype_ mod_fault = 0;
10123
10124 #if !defined(EIS_SETUP)
10125 setupOperandDescriptor(cpup, 1, &mod_fault);
10126 setupOperandDescriptor(cpup, 2, &mod_fault);
10127 #endif
10128
10129 PNL (L68_ (DU_CYCLE_DGDB;))
10130
10131 parseNumericOperandDescriptor(cpup, 1, &mod_fault);
10132 parseNumericOperandDescriptor(cpup, 2, &mod_fault);
10133
10134 L68_ (
10135
10136 if (mod_fault)
10137 {
10138 doFault (FAULT_IPR,
10139 (_fault_subtype) {.fault_ipr_subtype=mod_fault},
10140 "Illegal modifier");
10141 }
10142 )
10143
10144
10145 uint mbz = (uint) getbits36 (IWB_IRODD, 0, 11);
10146 if (mbz)
10147 {
10148 doFault (FAULT_IPR, (_fault_subtype) {.fault_ipr_subtype=FR_ILL_OP|mod_fault}, "dtb(): 0-10 MBZ");
10149 }
10150
10151
10152 if (!(e->MF[0] & MFkID) && e -> op [0] & 0000000007700)
10153 {
10154 doFault (FAULT_IPR, (_fault_subtype) {.fault_ipr_subtype=FR_ILL_PROC|mod_fault}, "dtb op1 24-29 MBZ");
10155 }
10156
10157
10158 if (!(e->MF[1] & MFkID) && e -> op [1] & 0000000077700)
10159 {
10160 doFault (FAULT_IPR, (_fault_subtype) {.fault_ipr_subtype=FR_ILL_PROC|mod_fault}, "dtb op2 21-29 MBZ");
10161 }
10162
10163
10164
10165 if (e->S1 == 0 || e->SF1 != 0)
10166 {
10167 doFault(FAULT_IPR, (_fault_subtype) {.fault_ipr_subtype=FR_ILL_PROC|mod_fault}, "dtb(): S1=0 or SF1!=0");
10168 }
10169
10170 DPS8M_ (
10171
10172 if (mod_fault)
10173 {
10174 doFault (FAULT_IPR,
10175 (_fault_subtype) {.fault_ipr_subtype=mod_fault},
10176 "Illegal modifier");
10177 }
10178 )
10179
10180
10181 if (e->N2 == 0 || e->N2 > 8)
10182 {
10183 doFault(FAULT_IPR, fst_ill_proc, "dtb(): N2 = 0 or N2 > 8 etc.");
10184 }
10185
10186 int n1 = 0;
10187
10188
10189
10190
10191
10192
10193
10194
10195
10196
10197
10198 switch(e->S1)
10199 {
10200 case CSLS:
10201 case CSTS:
10202 n1 = (int) e->N1 - 1;
10203 break;
10204
10205 case CSNS:
10206 n1 = (int) e->N1;
10207 break;
10208 }
10209
10210
10211
10212
10213 if (n1 < 1)
10214 doFault (FAULT_IPR, fst_ill_proc, "dtb adjusted n1<1");
10215
10216 EISloadInputBufferNumeric (cpup, 1);
10217
10218
10219 #if defined(NEED_128)
10220 word72 msk = subtract_128 (lshift_128 (construct_128 (0, 1), (9*e->N2-1)),construct_128 (0, 1));
10221 #else
10222 word72 msk = ((word72)1<<(9*e->N2-1))-1;
10223 #endif
10224
10225
10226
10227
10228
10229
10230
10231
10232
10233
10234
10235
10236
10237
10238
10239 bool Ovr = false;
10240 #if defined(NEED_128)
10241 word72 x = construct_128 (0, 0);
10242 for (int i = 0; i < n1; i++) {
10243
10244 x = multiply_128 (x, construct_128 (0, 10));
10245
10246 x = add_128 (x, construct_128 (0, (uint) e->inBuffer[i]));
10247
10248 Ovr |= isgt_128 (x, msk) ? 1 : 0;
10249
10250 x = and_128 (x, msk);
10251 }
10252 if (e->sign == -1)
10253
10254 x = negate_128 (x);
10255
10256 #else
10257 word72 x = 0;
10258 for (int i = 0; i < n1; i++) {
10259 x *= 10;
10260 x += e->inBuffer[i];
10261
10262 Ovr |= x>msk?1:0;
10263 x &= msk;
10264 }
10265 if (e->sign == -1)
10266
10267
10268 x = (word72) (- (word72s) x);
10269
10270
10271 #endif
10272 int pos = (int)e->CN2;
10273
10274
10275
10276 int shift = 9*((int)e->N2-1);
10277 for(int i = 0; i < (int)e->N2; i++) {
10278 #if defined(NEED_128)
10279 EISwrite9(cpup, &e->ADDR2, &pos, (word9) rshift_128 (x, (uint) shift).l & 0777);
10280 #else
10281 EISwrite9(cpup, &e->ADDR2, &pos, (word9) (x >> shift )& 0777);
10282 #endif
10283 shift -= 9;
10284 }
10285
10286 SC_I_NEG (e->sign == -1);
10287 #if defined(NEED_128)
10288 SC_I_ZERO (iszero_128 (x));
10289 #else
10290 SC_I_ZERO (x==0);
10291 #endif
10292
10293 cleanupOperandDescriptor (cpup, 1);
10294 cleanupOperandDescriptor (cpup, 2);
10295
10296 if (Ovr)
10297 {
10298 SET_I_OFLOW;
10299 if (tstOVFfault (cpup))
10300 doFault(FAULT_OFL, fst_zero, "dtb overflow fault");
10301 }
10302 }
10303
10304
10305
10306
10307
10308 #define ASC(x) ((x) + '0')
10309
10310
10311
10312
10313
10314 void ad2d (cpu_state_t * cpup)
10315 {
10316 EISstruct * e = & cpu.currentEISinstruction;
10317
10318 fault_ipr_subtype_ mod_fault = 0;
10319
10320 #if !defined(EIS_SETUP)
10321 setupOperandDescriptor(cpup, 1, &mod_fault);
10322 setupOperandDescriptor(cpup, 2, &mod_fault);
10323 setupOperandDescriptorCache(cpup,3);
10324 #endif
10325
10326 parseNumericOperandDescriptor(cpup, 1, &mod_fault);
10327 parseNumericOperandDescriptor(cpup, 2, &mod_fault);
10328
10329 L68_ (
10330
10331 if (mod_fault)
10332 {
10333 doFault (FAULT_IPR,
10334 (_fault_subtype) {.fault_ipr_subtype=mod_fault},
10335 "Illegal modifier");
10336 }
10337 )
10338
10339
10340 if (IWB_IRODD & 0377000000000)
10341 doFault (FAULT_IPR, fst_ill_op, "ad2d 1-8 MBZ");
10342
10343 DPS8M_ (
10344
10345 if (mod_fault)
10346 {
10347 doFault (FAULT_IPR,
10348 (_fault_subtype) {.fault_ipr_subtype=mod_fault},
10349 "Illegal modifier");
10350 }
10351 )
10352
10353 e->P = getbits36_1 (cpu.cu.IWB, 0) != 0;
10354 bool T = getbits36_1 (cpu.cu.IWB, 9) != 0;
10355 bool R = getbits36_1 (cpu.cu.IWB, 10) != 0;
10356
10357 PNL (L68_ (if (R)
10358 DU_CYCLE_FRND;))
10359
10360 uint srcTN = e->TN1;
10361
10362 uint dstTN = e->TN2;
10363 uint dstCN = e->CN2;
10364
10365 e->ADDR3 = e->ADDR2;
10366
10367 int n1 = 0, n2 = 0, sc1 = 0, sc2 = 0;
10368
10369
10370
10371
10372
10373
10374
10375
10376
10377
10378
10379 switch(e->S1)
10380 {
10381 case CSFL:
10382 n1 = (int) e->N1 - 1;
10383 if (srcTN == CTN4)
10384 n1 -= 2;
10385 else
10386 n1 -= 1;
10387 sc1 = 0;
10388 break;
10389
10390 case CSLS:
10391 case CSTS:
10392 n1 = (int) e->N1 - 1;
10393 sc1 = -e->SF1;
10394 break;
10395
10396 case CSNS:
10397 n1 = (int) e->N1;
10398 sc1 = -e->SF1;
10399 break;
10400 }
10401
10402 if (n1 < 1)
10403 doFault (FAULT_IPR, fst_ill_proc, "ad2d adjusted n1<1");
10404
10405 switch(e->S2)
10406 {
10407 case CSFL:
10408 n2 = (int) e->N2 - 1;
10409 if (e->TN2 == CTN4)
10410 n2 -= 2;
10411 else
10412 n2 -= 1;
10413 sc2 = 0;
10414 break;
10415
10416 case CSLS:
10417 case CSTS:
10418 n2 = (int) e->N2 - 1;
10419 sc2 = -e->SF2;
10420 break;
10421
10422 case CSNS:
10423 n2 = (int) e->N2;
10424 sc2 = -e->SF2;
10425 break;
10426 }
10427
10428 if (n2 < 1)
10429 doFault (FAULT_IPR, fst_ill_proc, "ad2d adjusted n2<1");
10430
10431 decContext set;
10432
10433 decContextDefaultDPS8(&set);
10434
10435 set.traps=0;
10436
10437 decNumber _1, _2, _3;
10438
10439 EISloadInputBufferNumeric (cpup, 1);
10440
10441 decNumber *op1 = decBCD9ToNumber(e->inBuffer, n1, sc1, &_1);
10442 if (e->sign == -1)
10443 op1->bits |= DECNEG;
10444 if (e->S1 == CSFL)
10445 op1->exponent = e->exponent;
10446
10447 EISloadInputBufferNumeric (cpup, 2);
10448
10449 decNumber *op2 = decBCD9ToNumber(e->inBuffer, n2, sc2, &_2);
10450 if (e->sign == -1)
10451 op2->bits |= DECNEG;
10452 if (e->S2 == CSFL)
10453 op2->exponent = e->exponent;
10454
10455 decNumber *op3 = decNumberAdd(&_3, op1, op2, &set);
10456
10457
10458 bool iOvr = 0;
10459 if (op3->digits > 63) {
10460 uint8_t pr[256];
10461
10462
10463 int sf = e->S3==CSFL?op3->exponent:e->SF3;
10464
10465 int ctz = 0;
10466 if (sf>0) {
10467 decNumberGetBCD(op3,pr);
10468 for (int i=op3->digits-1;i>=0 && pr[i]==0;i--)
10469 ctz ++;
10470 }
10471
10472 if (op3->digits - min(max(sf,0),ctz) > 63) {
10473 enum rounding safeR = decContextGetRounding(&set);
10474 int safe = set.digits;
10475 decNumber tmp;
10476
10477
10478 decContextSetRounding(&set, DEC_ROUND_DOWN);
10479 set.digits = op3->digits - min(max(sf,0),ctz) - 63;
10480 decNumberPlus(&tmp, op3, &set);
10481 set.digits = safe;
10482
10483 decNumberSubtract(op3, op3, &tmp, &set);
10484
10485
10486
10487 decContextSetRounding(&set, safeR);
10488 iOvr = 1;
10489 }
10490 }
10491
10492 bool Ovr = false, EOvr = false, Trunc = false;
10493
10494 uint8_t out [256];
10495 char *res = formatDecimal(out, &set, op3, n2, (int) e->S2, e->SF2, R, &Ovr, &Trunc);
10496
10497 Ovr |= iOvr;
10498
10499 if (decNumberIsZero(op3))
10500 op3->exponent = 127;
10501
10502
10503
10504
10505
10506
10507 int pos = (int) dstCN;
10508
10509
10510 switch(e->S2)
10511 {
10512 case CSFL:
10513 case CSLS:
10514 switch(dstTN)
10515 {
10516 case CTN4:
10517 if (e->P)
10518
10519
10520 EISwrite49(cpup, &e->ADDR3, &pos, (int) dstTN,
10521 (decNumberIsNegative(op3) && !decNumberIsZero(op3)) ? 015 : 013);
10522 else
10523 EISwrite49(cpup, &e->ADDR3, &pos, (int) dstTN,
10524 (decNumberIsNegative(op3) && !decNumberIsZero(op3)) ? 015 : 014);
10525 break;
10526 case CTN9:
10527 EISwrite49(cpup, &e->ADDR3, &pos, (int) dstTN,
10528 (decNumberIsNegative(op3) && !decNumberIsZero(op3)) ? '-' : '+');
10529 break;
10530 }
10531 break;
10532
10533 case CSTS:
10534 case CSNS:
10535 break;
10536 }
10537
10538
10539 for(int j = 0 ; j < n2 ; j++)
10540 switch(dstTN)
10541 {
10542 case CTN4:
10543 EISwrite49(cpup, &e->ADDR3, &pos, (int) dstTN, (word9) (res[j] - '0'));
10544 break;
10545 case CTN9:
10546 EISwrite49(cpup, &e->ADDR3, &pos, (int) dstTN, (word9) res[j]);
10547 break;
10548 }
10549
10550
10551 switch(e->S2)
10552 {
10553 case CSTS:
10554 switch(dstTN)
10555 {
10556 case CTN4:
10557 if (e->P)
10558
10559
10560 EISwrite49(cpup, &e->ADDR3, &pos, (int) dstTN,
10561 (decNumberIsNegative(op3) && !decNumberIsZero(op3)) ? 015 : 013);
10562 else
10563 EISwrite49(cpup, &e->ADDR3, &pos, (int) dstTN,
10564 (decNumberIsNegative(op3) && !decNumberIsZero(op3)) ? 015 : 014);
10565 break;
10566 case CTN9:
10567 EISwrite49(cpup, &e->ADDR3, &pos, (int) dstTN,
10568 (decNumberIsNegative(op3) && !decNumberIsZero(op3)) ? '-' : '+');
10569 break;
10570 }
10571 break;
10572
10573 case CSFL:
10574
10575 switch(dstTN)
10576 {
10577 case CTN4:
10578 EISwrite49(cpup, &e->ADDR3, &pos, (int) dstTN, (op3->exponent >> 4) & 0xf);
10579 EISwrite49(cpup, &e->ADDR3, &pos, (int) dstTN, op3->exponent & 0xf);
10580 break;
10581 case CTN9:
10582 EISwrite49(cpup, &e->ADDR3, &pos, (int) dstTN, op3->exponent & 0xff);
10583 break;
10584 }
10585 break;
10586
10587 case CSLS:
10588 case CSNS:
10589 break;
10590 }
10591
10592
10593 if (e->S2 == CSFL)
10594 {
10595 if (op3->exponent > 127)
10596 {
10597 SET_I_EOFL;
10598 EOvr = true;
10599 }
10600 if (op3->exponent < -128)
10601 {
10602 SET_I_EUFL;
10603 EOvr = true;
10604 }
10605 }
10606
10607 SC_I_NEG (decNumberIsNegative(op3) && !decNumberIsZero(op3));
10608 SC_I_ZERO (decNumberIsZero(op3));
10609
10610 SC_I_TRUNC (!R && Trunc);
10611
10612 cleanupOperandDescriptor (cpup, 1);
10613 cleanupOperandDescriptor (cpup, 2);
10614 cleanupOperandDescriptor (cpup, 3);
10615
10616 if (TST_I_TRUNC && T && tstOVFfault (cpup))
10617 doFault(FAULT_OFL, fst_zero, "ad2d truncation(overflow) fault");
10618 if (EOvr && tstOVFfault (cpup))
10619 doFault(FAULT_OFL, fst_zero, "ad2d over/underflow fault");
10620 if (Ovr)
10621 {
10622 SET_I_OFLOW;
10623 if (tstOVFfault (cpup))
10624 doFault(FAULT_OFL, fst_zero, "ad2d overflow fault");
10625 }
10626 }
10627
10628
10629
10630
10631
10632
10633
10634
10635
10636
10637
10638
10639
10640
10641
10642
10643
10644
10645
10646
10647
10648
10649
10650
10651
10652
10653
10654
10655
10656
10657
10658
10659
10660
10661
10662
10663
10664
10665
10666
10667
10668
10669
10670
10671
10672
10673 void ad3d (cpu_state_t * cpup)
10674 {
10675 EISstruct * e = & cpu.currentEISinstruction;
10676
10677 fault_ipr_subtype_ mod_fault = 0;
10678
10679 #if !defined(EIS_SETUP)
10680 setupOperandDescriptor(cpup, 1, &mod_fault);
10681 setupOperandDescriptor(cpup, 2, &mod_fault);
10682 setupOperandDescriptor(cpup, 3, &mod_fault);
10683 #endif
10684
10685 parseNumericOperandDescriptor(cpup, 1, &mod_fault);
10686 parseNumericOperandDescriptor(cpup, 2, &mod_fault);
10687 parseNumericOperandDescriptor(cpup, 3, &mod_fault);
10688
10689 L68_ (
10690
10691 if (mod_fault)
10692 {
10693 doFault (FAULT_IPR,
10694 (_fault_subtype) {.fault_ipr_subtype=mod_fault},
10695 "Illegal modifier");
10696 }
10697 )
10698
10699
10700 if (IWB_IRODD & 0200000000000)
10701 doFault (FAULT_IPR, (_fault_subtype) {.fault_ipr_subtype=FR_ILL_OP|mod_fault}, "ad3d(): 1 MBZ");
10702
10703 DPS8M_ (
10704
10705 if (mod_fault)
10706 {
10707 doFault (FAULT_IPR,
10708 (_fault_subtype) {.fault_ipr_subtype=mod_fault},
10709 "Illegal modifier");
10710 }
10711 )
10712
10713
10714 e->P = getbits36_1 (cpu.cu.IWB, 0) != 0;
10715 bool T = getbits36_1 (cpu.cu.IWB, 9) != 0;
10716 bool R = getbits36_1 (cpu.cu.IWB, 10) != 0;
10717
10718 PNL (L68_ (if (R)
10719 DU_CYCLE_FRND;))
10720
10721 uint srcTN = e->TN1;
10722
10723 uint dstTN = e->TN3;
10724 uint dstCN = e->CN3;
10725
10726 int n1 = 0, n2 = 0, n3 = 0, sc1 = 0, sc2 = 0;
10727
10728
10729
10730
10731
10732
10733
10734
10735
10736
10737
10738 switch(e->S1)
10739 {
10740 case CSFL:
10741 n1 = (int) e->N1 - 1;
10742 if (srcTN == CTN4)
10743 n1 -= 2;
10744 else
10745 n1 -= 1;
10746 sc1 = 0;
10747 break;
10748
10749 case CSLS:
10750 case CSTS:
10751 n1 = (int) e->N1 - 1;
10752 sc1 = -e->SF1;
10753 break;
10754
10755 case CSNS:
10756 n1 = (int) e->N1;
10757 sc1 = -e->SF1;
10758 break;
10759 }
10760
10761 if (n1 < 1)
10762 doFault (FAULT_IPR, fst_ill_proc, "ad3d adjusted n1<1");
10763
10764 switch(e->S2)
10765 {
10766 case CSFL:
10767 n2 = (int) e->N2 - 1;
10768 if (e->TN2 == CTN4)
10769 n2 -= 2;
10770 else
10771 n2 -= 1;
10772 sc2 = 0;
10773 break;
10774
10775 case CSLS:
10776 case CSTS:
10777 n2 = (int) e->N2 - 1;
10778 sc2 = -e->SF2;
10779 break;
10780
10781 case CSNS:
10782 n2 = (int) e->N2;
10783 sc2 = -e->SF2;
10784 break;
10785 }
10786
10787 if (n2 < 1)
10788 doFault (FAULT_IPR, fst_ill_proc, "ad3d adjusted n2<1");
10789
10790 switch(e->S3)
10791 {
10792 case CSFL:
10793 n3 = (int) e->N3 - 1;
10794 if (dstTN == CTN4)
10795 n3 -= 2;
10796 else
10797 n3 -= 1;
10798 break;
10799
10800 case CSLS:
10801 case CSTS:
10802 n3 = (int) e->N3 - 1;
10803 break;
10804
10805 case CSNS:
10806 n3 = (int) e->N3;
10807 break;
10808 }
10809
10810 if (n3 < 1)
10811 doFault (FAULT_IPR, fst_ill_proc, "ad3d adjusted n3<1");
10812
10813 decContext set;
10814
10815 decContextDefaultDPS8(&set);
10816 set.traps=0;
10817
10818 decNumber _1, _2, _3;
10819
10820 EISloadInputBufferNumeric (cpup, 1);
10821
10822 decNumber *op1 = decBCD9ToNumber(e->inBuffer, n1, sc1, &_1);
10823 if (e->sign == -1)
10824 op1->bits |= DECNEG;
10825 if (e->S1 == CSFL)
10826 op1->exponent = e->exponent;
10827
10828 EISloadInputBufferNumeric (cpup, 2);
10829
10830 decNumber *op2 = decBCD9ToNumber(e->inBuffer, n2, sc2, &_2);
10831 if (e->sign == -1)
10832 op2->bits |= DECNEG;
10833 if (e->S2 == CSFL)
10834 op2->exponent = e->exponent;
10835
10836 decNumber *op3 = decNumberAdd(&_3, op1, op2, &set);
10837
10838
10839
10840
10841
10842
10843
10844
10845
10846
10847
10848
10849 bool iOvr = 0;
10850 if (op3->digits > 63) {
10851 uint8_t pr[256];
10852
10853
10854 int sf = e->S3==CSFL?op3->exponent:e->SF3;
10855
10856 int ctz = 0;
10857 if (sf>0) {
10858 decNumberGetBCD(op3,pr);
10859 for (int i=op3->digits-1;i>=0 && pr[i]==0;i--)
10860 ctz ++;
10861 }
10862
10863 if (op3->digits - min(max(sf,0),ctz) > 63) {
10864 enum rounding safeR = decContextGetRounding(&set);
10865 int safe = set.digits;
10866 decNumber tmp;
10867
10868
10869 decContextSetRounding(&set, DEC_ROUND_DOWN);
10870 set.digits = op3->digits - min(max(sf,0),ctz) - 63;
10871 decNumberPlus(&tmp, op3, &set);
10872 set.digits = safe;
10873
10874 decNumberSubtract(op3, op3, &tmp, &set);
10875
10876
10877
10878 decContextSetRounding(&set, safeR);
10879 iOvr = 1;
10880 }
10881 }
10882
10883 bool Ovr = false, EOvr = false, Trunc = false;
10884
10885 uint8_t out [256];
10886 char *res = formatDecimal(out, &set, op3, n3, (int) e->S3, e->SF3, R, &Ovr, &Trunc);
10887
10888 Ovr |= iOvr;
10889
10890 if (decNumberIsZero(op3))
10891 op3->exponent = 127;
10892
10893
10894
10895
10896
10897
10898 int pos = (int) dstCN;
10899
10900
10901 switch(e->S3)
10902 {
10903 case CSFL:
10904 case CSLS:
10905 switch(dstTN)
10906 {
10907 case CTN4:
10908 if (e->P)
10909
10910
10911 EISwrite49(cpup, &e->ADDR3, &pos, (int) dstTN,
10912 (decNumberIsNegative(op3) && !decNumberIsZero(op3)) ? 015 : 013);
10913 else
10914 EISwrite49(cpup, &e->ADDR3, &pos, (int) dstTN,
10915 (decNumberIsNegative(op3) && !decNumberIsZero(op3)) ? 015 : 014);
10916 break;
10917 case CTN9:
10918 EISwrite49(cpup, &e->ADDR3, &pos, (int) dstTN,
10919 (decNumberIsNegative(op3) && !decNumberIsZero(op3)) ? '-' : '+');
10920 break;
10921 }
10922 break;
10923
10924 case CSTS:
10925 case CSNS:
10926 break;
10927 }
10928
10929
10930 for(int i = 0 ; i < n3 ; i++)
10931 switch(dstTN)
10932 {
10933 case CTN4:
10934 EISwrite49(cpup, &e->ADDR3, &pos, (int) dstTN, (word9) (res[i] - '0'));
10935 break;
10936 case CTN9:
10937 EISwrite49(cpup, &e->ADDR3, &pos, (int) dstTN, (word9) res[i]);
10938 break;
10939 }
10940
10941
10942 switch(e->S3)
10943 {
10944 case CSTS:
10945 switch(dstTN)
10946 {
10947 case CTN4:
10948 if (e->P)
10949
10950
10951 EISwrite49(cpup, &e->ADDR3, &pos, (int) dstTN,
10952 (decNumberIsNegative(op3) && !decNumberIsZero(op3)) ? 015 : 013);
10953 else
10954 EISwrite49(cpup, &e->ADDR3, &pos, (int) dstTN,
10955 (decNumberIsNegative(op3) && !decNumberIsZero(op3)) ? 015 : 014);
10956 break;
10957 case CTN9:
10958 EISwrite49(cpup, &e->ADDR3, &pos, (int) dstTN,
10959 (decNumberIsNegative(op3) && !decNumberIsZero(op3)) ? '-' : '+');
10960 break;
10961 }
10962 break;
10963
10964 case CSFL:
10965
10966 switch(dstTN)
10967 {
10968 case CTN4:
10969 EISwrite49(cpup, &e->ADDR3, &pos, (int) dstTN, (op3->exponent >> 4) & 0xf);
10970 EISwrite49(cpup, &e->ADDR3, &pos, (int) dstTN, op3->exponent & 0xf);
10971
10972 break;
10973 case CTN9:
10974 EISwrite49(cpup, &e->ADDR3, &pos, (int) dstTN, op3->exponent & 0xff);
10975 break;
10976 }
10977 break;
10978
10979 case CSLS:
10980 case CSNS:
10981 break;
10982 }
10983
10984
10985 if (e->S3 == CSFL)
10986 {
10987 if (op3->exponent > 127)
10988 {
10989 SET_I_EOFL;
10990 EOvr = true;
10991 }
10992 if (op3->exponent < -128)
10993 {
10994 SET_I_EUFL;
10995 EOvr = true;
10996 }
10997 }
10998
10999 SC_I_NEG (decNumberIsNegative(op3) && !decNumberIsZero(op3));
11000 SC_I_ZERO (decNumberIsZero(op3));
11001
11002 SC_I_TRUNC (!R && Trunc);
11003
11004 cleanupOperandDescriptor (cpup, 1);
11005 cleanupOperandDescriptor (cpup, 2);
11006 cleanupOperandDescriptor (cpup, 3);
11007
11008 if (TST_I_TRUNC && T && tstOVFfault (cpup))
11009 doFault(FAULT_OFL, fst_zero, "ad3d truncation(overflow) fault");
11010 if (EOvr && tstOVFfault (cpup))
11011 doFault(FAULT_OFL, fst_zero, "ad3d over/underflow fault");
11012 if (Ovr)
11013 {
11014 SET_I_OFLOW;
11015 if (tstOVFfault (cpup))
11016 doFault(FAULT_OFL, fst_zero, "ad3d overflow fault");
11017 }
11018 }
11019
11020
11021
11022
11023
11024 void sb2d (cpu_state_t * cpup)
11025 {
11026 EISstruct * e = & cpu.currentEISinstruction;
11027
11028 fault_ipr_subtype_ mod_fault = 0;
11029
11030 #if !defined(EIS_SETUP)
11031 setupOperandDescriptor(cpup, 1, &mod_fault);
11032 setupOperandDescriptor(cpup, 2, &mod_fault);
11033 setupOperandDescriptorCache(cpup,3);
11034 #endif
11035
11036 parseNumericOperandDescriptor(cpup, 1, &mod_fault);
11037 parseNumericOperandDescriptor(cpup, 2, &mod_fault);
11038
11039 L68_ (
11040
11041 if (mod_fault)
11042 {
11043 doFault (FAULT_IPR,
11044 (_fault_subtype) {.fault_ipr_subtype=mod_fault},
11045 "Illegal modifier");
11046 }
11047 )
11048
11049
11050 if (IWB_IRODD & 0377000000000)
11051 {
11052
11053 doFault (FAULT_IPR, (_fault_subtype) {.fault_ipr_subtype=FR_ILL_OP|mod_fault}, "sb2d 0-8 MBZ");
11054 }
11055
11056 DPS8M_ (
11057
11058 if (mod_fault)
11059 {
11060 doFault (FAULT_IPR,
11061 (_fault_subtype) {.fault_ipr_subtype=mod_fault},
11062 "Illegal modifier");
11063 }
11064 )
11065
11066 e->P = getbits36_1 (cpu.cu.IWB, 0) != 0;
11067 bool T = getbits36_1 (cpu.cu.IWB, 9) != 0;
11068 bool R = getbits36_1 (cpu.cu.IWB, 10) != 0;
11069
11070 PNL (L68_ (if (R)
11071 DU_CYCLE_FRND;))
11072
11073 uint srcTN = e->TN1;
11074
11075 uint dstTN = e->TN2;
11076 uint dstCN = e->CN2;
11077
11078 e->ADDR3 = e->ADDR2;
11079
11080 int n1 = 0, n2 = 0, sc1 = 0, sc2 = 0;
11081
11082
11083
11084
11085
11086
11087
11088
11089
11090
11091
11092 switch(e->S1)
11093 {
11094 case CSFL:
11095 n1 = (int) e->N1 - 1;
11096 if (srcTN == CTN4)
11097 n1 -= 2;
11098 else
11099 n1 -= 1;
11100 sc1 = 0;
11101 break;
11102
11103 case CSLS:
11104 case CSTS:
11105 n1 = (int) e->N1 - 1;
11106 sc1 = -e->SF1;
11107 break;
11108
11109 case CSNS:
11110 n1 = (int) e->N1;
11111 sc1 = -e->SF1;
11112 break;
11113 }
11114
11115 if (n1 < 1)
11116 doFault (FAULT_IPR, fst_ill_proc, "sb2d adjusted n1<1");
11117
11118 switch(e->S2)
11119 {
11120 case CSFL:
11121 n2 = (int) e->N2 - 1;
11122 if (e->TN2 == CTN4)
11123 n2 -= 2;
11124 else
11125 n2 -= 1;
11126 sc2 = 0;
11127 break;
11128
11129 case CSLS:
11130 case CSTS:
11131 n2 = (int) e->N2 - 1;
11132 sc2 = -e->SF2;
11133 break;
11134
11135 case CSNS:
11136 n2 = (int) e->N2;
11137 sc2 = -e->SF2;
11138 break;
11139 }
11140
11141 if (n2 < 1)
11142 doFault (FAULT_IPR, fst_ill_proc, "sb2d adjusted n2<1");
11143
11144 decContext set;
11145
11146 decContextDefaultDPS8(&set);
11147 set.traps=0;
11148
11149 decNumber _1, _2, _3;
11150
11151 EISloadInputBufferNumeric (cpup, 1);
11152
11153 decNumber *op1 = decBCD9ToNumber(e->inBuffer, n1, sc1, &_1);
11154 if (e->sign == -1)
11155 op1->bits |= DECNEG;
11156 if (e->S1 == CSFL)
11157 op1->exponent = e->exponent;
11158
11159 EISloadInputBufferNumeric (cpup, 2);
11160
11161 decNumber *op2 = decBCD9ToNumber(e->inBuffer, n2, sc2, &_2);
11162 if (e->sign == -1)
11163 op2->bits |= DECNEG;
11164 if (e->S2 == CSFL)
11165 op2->exponent = e->exponent;
11166
11167 decNumber *op3 = decNumberSubtract(&_3, op2, op1, &set);
11168
11169
11170 bool iOvr = 0;
11171 if (op3->digits > 63) {
11172 uint8_t pr[256];
11173
11174
11175 int sf = e->S3==CSFL?op3->exponent:e->SF3;
11176
11177 int ctz = 0;
11178 if (sf>0) {
11179 decNumberGetBCD(op3,pr);
11180 for (int i=op3->digits-1;i>=0 && pr[i]==0;i--)
11181 ctz ++;
11182 }
11183
11184 if (op3->digits - min(max(sf,0),ctz) > 63) {
11185 enum rounding safeR = decContextGetRounding(&set);
11186 int safe = set.digits;
11187 decNumber tmp;
11188
11189
11190 decContextSetRounding(&set, DEC_ROUND_DOWN);
11191 set.digits = op3->digits - min(max(sf,0),ctz) - 63;
11192 decNumberPlus(&tmp, op3, &set);
11193 set.digits = safe;
11194
11195 decNumberSubtract(op3, op3, &tmp, &set);
11196
11197
11198
11199 decContextSetRounding(&set, safeR);
11200 iOvr = 1;
11201 }
11202 }
11203
11204 bool Ovr = false, EOvr = false, Trunc = false;
11205
11206 uint8_t out [256];
11207 char *res = formatDecimal(out, &set, op3, n2, (int) e->S2, e->SF2, R, &Ovr, &Trunc);
11208
11209 Ovr |= iOvr;
11210
11211 if (decNumberIsZero(op3))
11212 op3->exponent = 127;
11213
11214
11215
11216
11217
11218
11219 int pos = (int) dstCN;
11220
11221
11222 switch(e->S2)
11223 {
11224 case CSFL:
11225 case CSLS:
11226 switch(dstTN)
11227 {
11228 case CTN4:
11229 if (e->P)
11230
11231
11232 EISwrite49(cpup, &e->ADDR3, &pos, (int) dstTN,
11233 (decNumberIsNegative(op3) && !decNumberIsZero(op3)) ? 015 : 013);
11234 else
11235 EISwrite49(cpup, &e->ADDR3, &pos, (int) dstTN,
11236 (decNumberIsNegative(op3) && !decNumberIsZero(op3)) ? 015 : 014);
11237 break;
11238 case CTN9:
11239 EISwrite49(cpup, &e->ADDR3, &pos, (int) dstTN,
11240 (decNumberIsNegative(op3) && !decNumberIsZero(op3)) ? '-' : '+');
11241 break;
11242 }
11243 break;
11244
11245 case CSTS:
11246 case CSNS:
11247 break;
11248 }
11249
11250
11251 for(int i = 0 ; i < n2 ; i++)
11252 switch(dstTN)
11253 {
11254 case CTN4:
11255 EISwrite49(cpup, &e->ADDR3, &pos, (int) dstTN, (word9) (res[i] - '0'));
11256 break;
11257 case CTN9:
11258 EISwrite49(cpup, &e->ADDR3, &pos, (int) dstTN, (word9) res[i]);
11259 break;
11260 }
11261
11262
11263 switch(e->S2)
11264 {
11265 case CSTS:
11266 switch(dstTN)
11267 {
11268 case CTN4:
11269 if (e->P)
11270
11271
11272 EISwrite49(cpup, &e->ADDR3, &pos, (int) dstTN,
11273 (decNumberIsNegative(op3) && !decNumberIsZero(op3)) ? 015 : 013);
11274 else
11275 EISwrite49(cpup, &e->ADDR3, &pos, (int) dstTN,
11276 (decNumberIsNegative(op3) && !decNumberIsZero(op3)) ? 015 : 014);
11277 break;
11278 case CTN9:
11279 EISwrite49(cpup, &e->ADDR3, &pos, (int) dstTN,
11280 (decNumberIsNegative(op3) && !decNumberIsZero(op3)) ? '-' : '+');
11281 break;
11282 }
11283 break;
11284
11285 case CSFL:
11286
11287 switch(dstTN)
11288 {
11289 case CTN4:
11290 EISwrite49(cpup, &e->ADDR3, &pos, (int) dstTN, (op3->exponent >> 4) & 0xf);
11291 EISwrite49(cpup, &e->ADDR3, &pos, (int) dstTN, op3->exponent & 0xf);
11292
11293 break;
11294 case CTN9:
11295 EISwrite49(cpup, &e->ADDR3, &pos, (int) dstTN, op3->exponent & 0xff);
11296 break;
11297 }
11298 break;
11299
11300 case CSLS:
11301 case CSNS:
11302 break;
11303 }
11304
11305
11306 if (e->S2 == CSFL)
11307 {
11308 if (op3->exponent > 127)
11309 {
11310 SET_I_EOFL;
11311 EOvr = true;
11312 }
11313 if (op3->exponent < -128)
11314 {
11315 SET_I_EUFL;
11316 EOvr = true;
11317 }
11318 }
11319
11320 SC_I_NEG (decNumberIsNegative(op3) && !decNumberIsZero(op3));
11321 SC_I_ZERO (decNumberIsZero(op3));
11322
11323 SC_I_TRUNC (!R && Trunc);
11324
11325 cleanupOperandDescriptor (cpup, 1);
11326 cleanupOperandDescriptor (cpup, 2);
11327 cleanupOperandDescriptor (cpup, 3);
11328
11329 if (TST_I_TRUNC && T && tstOVFfault (cpup))
11330 doFault(FAULT_OFL, fst_zero, "sb2d truncation(overflow) fault");
11331 if (EOvr && tstOVFfault (cpup))
11332 doFault(FAULT_OFL, fst_zero, "sb2d over/underflow fault");
11333 if (Ovr)
11334 {
11335 SET_I_OFLOW;
11336 if (tstOVFfault (cpup))
11337 doFault(FAULT_OFL, fst_zero, "sb2d overflow fault");
11338 }
11339 }
11340
11341
11342
11343
11344
11345 void sb3d (cpu_state_t * cpup)
11346 {
11347 EISstruct * e = & cpu.currentEISinstruction;
11348
11349 fault_ipr_subtype_ mod_fault = 0;
11350
11351 #if !defined(EIS_SETUP)
11352 setupOperandDescriptor(cpup, 1, &mod_fault);
11353 setupOperandDescriptor(cpup, 2, &mod_fault);
11354 setupOperandDescriptor(cpup, 3, &mod_fault);
11355 #endif
11356
11357 parseNumericOperandDescriptor(cpup, 1, &mod_fault);
11358 parseNumericOperandDescriptor(cpup, 2, &mod_fault);
11359 parseNumericOperandDescriptor(cpup, 3, &mod_fault);
11360
11361 L68_ (
11362
11363 if (mod_fault)
11364 {
11365 doFault (FAULT_IPR,
11366 (_fault_subtype) {.fault_ipr_subtype=mod_fault},
11367 "Illegal modifier");
11368 }
11369 )
11370
11371
11372 if (IWB_IRODD & 0200000000000)
11373 doFault (FAULT_IPR, (_fault_subtype) {.fault_ipr_subtype=FR_ILL_OP|mod_fault}, "sb3d(): 1 MBZ");
11374
11375 DPS8M_ (
11376
11377 if (mod_fault)
11378 {
11379 doFault (FAULT_IPR,
11380 (_fault_subtype) {.fault_ipr_subtype=mod_fault},
11381 "Illegal modifier");
11382 }
11383 )
11384
11385 e->P = getbits36_1 (cpu.cu.IWB, 0) != 0;
11386 bool T = getbits36_1 (cpu.cu.IWB, 9) != 0;
11387 bool R = getbits36_1 (cpu.cu.IWB, 10) != 0;
11388
11389 PNL (L68_ (if (R)
11390 DU_CYCLE_FRND;))
11391
11392 uint srcTN = e->TN1;
11393
11394 uint dstTN = e->TN3;
11395 uint dstCN = e->CN3;
11396
11397 int n1 = 0, n2 = 0, n3 = 0, sc1 = 0, sc2 = 0;
11398
11399
11400
11401
11402
11403
11404
11405
11406
11407
11408
11409 switch(e->S1)
11410 {
11411 case CSFL:
11412 n1 = (int) e->N1 - 1;
11413 if (srcTN == CTN4)
11414 n1 -= 2;
11415 else
11416 n1 -= 1;
11417 sc1 = 0;
11418 break;
11419
11420 case CSLS:
11421 case CSTS:
11422 n1 = (int) e->N1 - 1;
11423 sc1 = -e->SF1;
11424 break;
11425
11426 case CSNS:
11427 n1 = (int) e->N1;
11428 sc1 = -e->SF1;
11429 break;
11430 }
11431
11432 if (n1 < 1)
11433 doFault (FAULT_IPR, fst_ill_proc, "sb3d adjusted n1<1");
11434
11435 switch(e->S2)
11436 {
11437 case CSFL:
11438 n2 = (int) e->N2 - 1;
11439 if (e->TN2 == CTN4)
11440 n2 -= 2;
11441 else
11442 n2 -= 1;
11443 sc2 = 0;
11444 break;
11445
11446 case CSLS:
11447 case CSTS:
11448 n2 = (int) e->N2 - 1;
11449 sc2 = -e->SF2;
11450 break;
11451
11452 case CSNS:
11453 n2 = (int) e->N2;
11454 sc2 = -e->SF2;
11455 break;
11456 }
11457
11458 if (n2 < 1)
11459 doFault (FAULT_IPR, fst_ill_proc, "sb3d adjusted n2<1");
11460
11461 switch(e->S3)
11462 {
11463 case CSFL:
11464 n3 = (int) e->N3 - 1;
11465 if (dstTN == CTN4)
11466 n3 -= 2;
11467 else
11468 n3 -= 1;
11469 break;
11470
11471 case CSLS:
11472 case CSTS:
11473 n3 = (int) e->N3 - 1;
11474 break;
11475
11476 case CSNS:
11477 n3 = (int) e->N3;
11478 break;
11479 }
11480
11481 if (n3 < 1)
11482 doFault (FAULT_IPR, fst_ill_proc, "sb3d adjusted n3<1");
11483
11484 decContext set;
11485
11486 decContextDefaultDPS8(&set);
11487
11488 set.traps=0;
11489
11490 decNumber _1, _2, _3;
11491
11492 EISloadInputBufferNumeric (cpup, 1);
11493
11494 decNumber *op1 = decBCD9ToNumber(e->inBuffer, n1, sc1, &_1);
11495 if (e->sign == -1)
11496 op1->bits |= DECNEG;
11497 if (e->S1 == CSFL)
11498 op1->exponent = e->exponent;
11499
11500 EISloadInputBufferNumeric (cpup, 2);
11501
11502 decNumber *op2 = decBCD9ToNumber(e->inBuffer, n2, sc2, &_2);
11503 if (e->sign == -1)
11504 op2->bits |= DECNEG;
11505 if (e->S2 == CSFL)
11506 op2->exponent = e->exponent;
11507
11508 decNumber *op3 = decNumberSubtract(&_3, op2, op1, &set);
11509
11510
11511 bool iOvr = 0;
11512 if (op3->digits > 63) {
11513 uint8_t pr[256];
11514
11515
11516 int sf = e->S3==CSFL?op3->exponent:e->SF3;
11517
11518 int ctz = 0;
11519 if (sf>0) {
11520 decNumberGetBCD(op3,pr);
11521 for (int i=op3->digits-1;i>=0 && pr[i]==0;i--)
11522 ctz ++;
11523 }
11524
11525 if (op3->digits - min(max(sf,0),ctz) > 63) {
11526 enum rounding safeR = decContextGetRounding(&set);
11527 int safe = set.digits;
11528 decNumber tmp;
11529
11530
11531 decContextSetRounding(&set, DEC_ROUND_DOWN);
11532 set.digits = op3->digits - min(max(sf,0),ctz) - 63;
11533 decNumberPlus(&tmp, op3, &set);
11534 set.digits = safe;
11535
11536 decNumberSubtract(op3, op3, &tmp, &set);
11537
11538
11539
11540 decContextSetRounding(&set, safeR);
11541 iOvr = 1;
11542 }
11543 }
11544
11545 bool Ovr = false, EOvr = false, Trunc = false;
11546
11547 uint8_t out [256];
11548 char *res = formatDecimal(out, &set, op3, n3, (int) e->S3, e->SF3, R, &Ovr, &Trunc);
11549
11550 Ovr |= iOvr;
11551
11552 if (decNumberIsZero(op3))
11553 op3->exponent = 127;
11554
11555
11556
11557
11558 int pos = (int) dstCN;
11559
11560
11561 switch(e->S3)
11562 {
11563 case CSFL:
11564 case CSLS:
11565 switch(dstTN)
11566 {
11567 case CTN4:
11568 if (e->P)
11569
11570
11571 EISwrite49(cpup, &e->ADDR3, &pos, (int) dstTN,
11572 (decNumberIsNegative(op3) && !decNumberIsZero(op3)) ? 015 : 013);
11573 else
11574 EISwrite49(cpup, &e->ADDR3, &pos, (int) dstTN,
11575 (decNumberIsNegative(op3) && !decNumberIsZero(op3)) ? 015 : 014);
11576 break;
11577 case CTN9:
11578 EISwrite49(cpup, &e->ADDR3, &pos, (int) dstTN,
11579 (decNumberIsNegative(op3) && !decNumberIsZero(op3)) ? '-' : '+');
11580 break;
11581 }
11582 break;
11583
11584 case CSTS:
11585 case CSNS:
11586 break;
11587 }
11588
11589
11590 for(int i = 0 ; i < n3 ; i++)
11591 switch(dstTN)
11592 {
11593 case CTN4:
11594 EISwrite49(cpup, &e->ADDR3, &pos, (int) dstTN, (word9) (res[i] - '0'));
11595 break;
11596 case CTN9:
11597 EISwrite49(cpup, &e->ADDR3, &pos, (int) dstTN, (word9) res[i]);
11598 break;
11599 }
11600
11601
11602 switch(e->S3)
11603 {
11604 case CSTS:
11605 switch(dstTN)
11606 {
11607 case CTN4:
11608 if (e->P)
11609
11610
11611 EISwrite49(cpup, &e->ADDR3, &pos, (int) dstTN,
11612 (decNumberIsNegative(op3) && !decNumberIsZero(op3)) ? 015 : 013);
11613 else
11614 EISwrite49(cpup, &e->ADDR3, &pos, (int) dstTN,
11615 (decNumberIsNegative(op3) && !decNumberIsZero(op3)) ? 015 : 014);
11616 break;
11617 case CTN9:
11618 EISwrite49(cpup, &e->ADDR3, &pos, (int) dstTN,
11619 (decNumberIsNegative(op3) && !decNumberIsZero(op3)) ? '-' : '+');
11620 break;
11621 }
11622 break;
11623
11624 case CSFL:
11625
11626 switch(dstTN)
11627 {
11628 case CTN4:
11629 EISwrite49(cpup, &e->ADDR3, &pos, (int) dstTN, (op3->exponent >> 4) & 0xf);
11630 EISwrite49(cpup, &e->ADDR3, &pos, (int) dstTN, op3->exponent & 0xf);
11631
11632 break;
11633 case CTN9:
11634 EISwrite49(cpup, &e->ADDR3, &pos, (int) dstTN, op3->exponent & 0xff);
11635 break;
11636 }
11637 break;
11638
11639 case CSLS:
11640 case CSNS:
11641 break;
11642 }
11643
11644
11645 if (e->S3 == CSFL)
11646 {
11647 if (op3->exponent > 127)
11648 {
11649 SET_I_EOFL;
11650 EOvr = true;
11651 }
11652 if (op3->exponent < -128)
11653 {
11654 SET_I_EUFL;
11655 EOvr = true;
11656 }
11657 }
11658
11659 SC_I_NEG (decNumberIsNegative(op3) && !decNumberIsZero(op3));
11660 SC_I_ZERO (decNumberIsZero(op3));
11661
11662 SC_I_TRUNC (!R && Trunc);
11663
11664 cleanupOperandDescriptor (cpup, 1);
11665 cleanupOperandDescriptor (cpup, 2);
11666 cleanupOperandDescriptor (cpup, 3);
11667
11668 if (TST_I_TRUNC && T && tstOVFfault (cpup))
11669 doFault(FAULT_OFL, fst_zero, "sb3d truncation(overflow) fault");
11670 if (EOvr && tstOVFfault (cpup))
11671 doFault(FAULT_OFL, fst_zero, "sb3d over/underflow fault");
11672 if (Ovr)
11673 {
11674 SET_I_OFLOW;
11675 if (tstOVFfault (cpup))
11676 doFault(FAULT_OFL, fst_zero, "sb3d overflow fault");
11677 }
11678 }
11679
11680
11681
11682
11683
11684 void mp2d (cpu_state_t * cpup)
11685 {
11686 EISstruct * e = & cpu.currentEISinstruction;
11687
11688 fault_ipr_subtype_ mod_fault = 0;
11689
11690 #if !defined(EIS_SETUP)
11691 setupOperandDescriptor(cpup, 1, &mod_fault);
11692 setupOperandDescriptor(cpup, 2, &mod_fault);
11693 setupOperandDescriptorCache(cpup,3);
11694 #endif
11695
11696 parseNumericOperandDescriptor(cpup, 1, &mod_fault);
11697 parseNumericOperandDescriptor(cpup, 2, &mod_fault);
11698
11699 L68_ (
11700
11701 if (mod_fault)
11702 {
11703 doFault (FAULT_IPR,
11704 (_fault_subtype) {.fault_ipr_subtype=mod_fault},
11705 "Illegal modifier");
11706 }
11707 )
11708
11709
11710 if (IWB_IRODD & 0377000000000)
11711 doFault (FAULT_IPR, (_fault_subtype) {.fault_ipr_subtype=FR_ILL_OP|mod_fault}, "mp2d 1-8 MBZ");
11712
11713 DPS8M_ (
11714
11715 if (mod_fault)
11716 {
11717 doFault (FAULT_IPR,
11718 (_fault_subtype) {.fault_ipr_subtype=mod_fault},
11719 "Illegal modifier");
11720 }
11721 )
11722
11723 e->P = getbits36_1 (cpu.cu.IWB, 0) != 0;
11724 bool T = getbits36_1 (cpu.cu.IWB, 9) != 0;
11725 bool R = getbits36_1 (cpu.cu.IWB, 10) != 0;
11726
11727 PNL (L68_ (if (R)
11728 DU_CYCLE_FRND;))
11729
11730 uint srcTN = e->TN1;
11731
11732 uint dstTN = e->TN2;
11733 uint dstCN = e->CN2;
11734
11735 e->ADDR3 = e->ADDR2;
11736
11737 int n1 = 0, n2 = 0, sc1 = 0, sc2 = 0;
11738
11739
11740
11741
11742
11743
11744
11745
11746
11747
11748
11749 switch(e->S1)
11750 {
11751 case CSFL:
11752 n1 = (int) e->N1 - 1;
11753 if (srcTN == CTN4)
11754 n1 -= 2;
11755 else
11756 n1 -= 1;
11757 sc1 = 0;
11758 break;
11759
11760 case CSLS:
11761 case CSTS:
11762 n1 = (int) e->N1 - 1;
11763 sc1 = -e->SF1;
11764 break;
11765
11766 case CSNS:
11767 n1 = (int) e->N1;
11768 sc1 = -e->SF1;
11769 break;
11770 }
11771
11772 if (n1 < 1)
11773 doFault (FAULT_IPR, fst_ill_proc, "mp2d adjusted n1<1");
11774
11775 switch(e->S2)
11776 {
11777 case CSFL:
11778 n2 = (int) e->N2 - 1;
11779 if (e->TN2 == CTN4)
11780 n2 -= 2;
11781 else
11782 n2 -= 1;
11783 sc2 = 0;
11784 break;
11785
11786 case CSLS:
11787 case CSTS:
11788 n2 = (int) e->N2 - 1;
11789 sc2 = -e->SF2;
11790 break;
11791
11792 case CSNS:
11793 n2 = (int) e->N2;
11794 sc2 = -e->SF2;
11795 break;
11796 }
11797
11798 if (n2 < 1)
11799 doFault (FAULT_IPR, fst_ill_proc, "mp2d adjusted n2<1");
11800
11801 decContext set;
11802 decContextDefaultDPS8Mul(&set);
11803
11804 set.traps=0;
11805
11806 decNumber _1, _2, _3;
11807
11808 EISloadInputBufferNumeric (cpup, 1);
11809
11810 decNumber *op1 = decBCD9ToNumber(e->inBuffer, n1, sc1, &_1);
11811 if (e->sign == -1)
11812 op1->bits |= DECNEG;
11813 if (e->S1 == CSFL)
11814 op1->exponent = e->exponent;
11815
11816 EISloadInputBufferNumeric (cpup, 2);
11817
11818 decNumber *op2 = decBCD9ToNumber(e->inBuffer, n2, sc2, &_2);
11819 if (e->sign == -1)
11820 op2->bits |= DECNEG;
11821 if (e->S2 == CSFL)
11822 op2->exponent = e->exponent;
11823
11824 decNumber *op3 = decNumberMultiply(&_3, op1, op2, &set);
11825
11826 bool Ovr = false, EOvr = false, Trunc = false;
11827
11828 uint8_t out [256];
11829 char *res = formatDecimal(out, &set, op3, n2, (int) e->S2, e->SF2, R, &Ovr, &Trunc);
11830
11831 if (decNumberIsZero(op3))
11832 op3->exponent = 127;
11833
11834
11835
11836
11837 int pos = (int) dstCN;
11838
11839
11840 switch(e->S2)
11841 {
11842 case CSFL:
11843 case CSLS:
11844 switch(dstTN)
11845 {
11846 case CTN4:
11847 if (e->P)
11848
11849
11850 EISwrite49(cpup, &e->ADDR3, &pos, (int) dstTN,
11851 (decNumberIsNegative(op3) && !decNumberIsZero(op3)) ? 015 : 013);
11852 else
11853 EISwrite49(cpup, &e->ADDR3, &pos, (int) dstTN,
11854 (decNumberIsNegative(op3) && !decNumberIsZero(op3)) ? 015 : 014);
11855 break;
11856 case CTN9:
11857 EISwrite49(cpup, &e->ADDR3, &pos, (int) dstTN,
11858 (decNumberIsNegative(op3) && !decNumberIsZero(op3)) ? '-' : '+');
11859 break;
11860 }
11861 break;
11862
11863 case CSTS:
11864 case CSNS:
11865 break;
11866 }
11867
11868
11869 for(int i = 0 ; i < n2 ; i++)
11870 switch(dstTN)
11871 {
11872 case CTN4:
11873 EISwrite49(cpup, &e->ADDR3, &pos, (int) dstTN, (word9) (res[i] - '0'));
11874 break;
11875 case CTN9:
11876 EISwrite49(cpup, &e->ADDR3, &pos, (int) dstTN, (word9) res[i]);
11877 break;
11878 }
11879
11880
11881 switch(e->S2)
11882 {
11883 case CSTS:
11884 switch(dstTN)
11885 {
11886 case CTN4:
11887 if (e->P)
11888
11889
11890 EISwrite49(cpup, &e->ADDR3, &pos, (int) dstTN,
11891 (decNumberIsNegative(op3) && !decNumberIsZero(op3)) ? 015 : 013);
11892 else
11893 EISwrite49(cpup, &e->ADDR3, &pos, (int) dstTN,
11894 (decNumberIsNegative(op3) && !decNumberIsZero(op3)) ? 015 : 014);
11895 break;
11896 case CTN9:
11897 EISwrite49(cpup, &e->ADDR3, &pos, (int) dstTN,
11898 (decNumberIsNegative(op3) && !decNumberIsZero(op3)) ? '-' : '+');
11899 break;
11900 }
11901 break;
11902
11903 case CSFL:
11904
11905 switch(dstTN)
11906 {
11907 case CTN4:
11908 EISwrite49(cpup, &e->ADDR3, &pos, (int) dstTN, (op3->exponent >> 4) & 0xf);
11909 EISwrite49(cpup, &e->ADDR3, &pos, (int) dstTN, op3->exponent & 0xf);
11910
11911 break;
11912 case CTN9:
11913 EISwrite49(cpup, &e->ADDR3, &pos, (int) dstTN, op3->exponent & 0xff);
11914 break;
11915 }
11916 break;
11917
11918 case CSLS:
11919 case CSNS:
11920 break;
11921 }
11922
11923
11924 if (e->S2 == CSFL)
11925 {
11926 if (op3->exponent > 127)
11927 {
11928 SET_I_EOFL;
11929 EOvr = true;
11930 }
11931 if (op3->exponent < -128)
11932 {
11933 SET_I_EUFL;
11934 EOvr = true;
11935 }
11936 }
11937
11938 SC_I_NEG (decNumberIsNegative(op3) && !decNumberIsZero(op3));
11939 SC_I_ZERO (decNumberIsZero(op3));
11940
11941 SC_I_TRUNC (!R && Trunc);
11942
11943 cleanupOperandDescriptor (cpup, 1);
11944 cleanupOperandDescriptor (cpup, 2);
11945 cleanupOperandDescriptor (cpup, 3);
11946
11947 if (TST_I_TRUNC && T && tstOVFfault (cpup))
11948 doFault(FAULT_OFL, fst_zero, "mp2d truncation(overflow) fault");
11949 if (EOvr && tstOVFfault (cpup))
11950 doFault(FAULT_OFL, fst_zero, "mp2d over/underflow fault");
11951 if (Ovr)
11952 {
11953 SET_I_OFLOW;
11954 if (tstOVFfault (cpup))
11955 doFault(FAULT_OFL, fst_zero, "mp2d overflow fault");
11956 }
11957 }
11958
11959
11960
11961
11962
11963 void mp3d (cpu_state_t * cpup)
11964 {
11965 EISstruct * e = & cpu.currentEISinstruction;
11966
11967 fault_ipr_subtype_ mod_fault = 0;
11968
11969 #if !defined(EIS_SETUP)
11970 setupOperandDescriptor(cpup, 1, &mod_fault);
11971 setupOperandDescriptor(cpup, 2, &mod_fault);
11972 setupOperandDescriptor(cpup, 3, &mod_fault);
11973 #endif
11974
11975 parseNumericOperandDescriptor(cpup, 1, &mod_fault);
11976 parseNumericOperandDescriptor(cpup, 2, &mod_fault);
11977 parseNumericOperandDescriptor(cpup, 3, &mod_fault);
11978
11979 L68_ (
11980
11981 if (mod_fault)
11982 {
11983 doFault (FAULT_IPR,
11984 (_fault_subtype) {.fault_ipr_subtype=mod_fault},
11985 "Illegal modifier");
11986 }
11987 )
11988
11989
11990 if (IWB_IRODD & 0200000000000)
11991 doFault (FAULT_IPR, (_fault_subtype) {.fault_ipr_subtype=FR_ILL_OP|mod_fault}, "mp3d(): 1 MBZ");
11992
11993 DPS8M_ (
11994
11995 if (mod_fault)
11996 {
11997 doFault (FAULT_IPR,
11998 (_fault_subtype) {.fault_ipr_subtype=mod_fault},
11999 "Illegal modifier");
12000 }
12001 )
12002
12003 e->P = getbits36_1 (cpu.cu.IWB, 0) != 0;
12004 bool T = getbits36_1 (cpu.cu.IWB, 9) != 0;
12005 bool R = getbits36_1 (cpu.cu.IWB, 10) != 0;
12006
12007 PNL (L68_ (if (R)
12008 DU_CYCLE_FRND;))
12009
12010 uint srcTN = e->TN1;
12011
12012 uint dstTN = e->TN3;
12013 uint dstCN = e->CN3;
12014
12015 int n1 = 0, n2 = 0, n3 = 0, sc1 = 0, sc2 = 0;
12016
12017
12018
12019
12020
12021
12022
12023
12024
12025
12026
12027 switch(e->S1)
12028 {
12029 case CSFL:
12030 n1 = (int) e->N1 - 1;
12031 if (srcTN == CTN4)
12032 n1 -= 2;
12033 else
12034 n1 -= 1;
12035 sc1 = 0;
12036 break;
12037
12038 case CSLS:
12039 case CSTS:
12040 n1 = (int) e->N1 - 1;
12041 sc1 = -e->SF1;
12042 break;
12043
12044 case CSNS:
12045 n1 = (int) e->N1;
12046 sc1 = -e->SF1;
12047 break;
12048 }
12049
12050 if (n1 < 1)
12051 doFault (FAULT_IPR, fst_ill_proc, "mp3d adjusted n1<1");
12052
12053 switch(e->S2)
12054 {
12055 case CSFL:
12056 n2 = (int) e->N2 - 1;
12057 if (e->TN2 == CTN4)
12058 n2 -= 2;
12059 else
12060 n2 -= 1;
12061 sc2 = 0;
12062 break;
12063
12064 case CSLS:
12065 case CSTS:
12066 n2 = (int) e->N2 - 1;
12067 sc2 = -e->SF2;
12068 break;
12069
12070 case CSNS:
12071 n2 = (int) e->N2;
12072 sc2 = -e->SF2;
12073 break;
12074 }
12075
12076 if (n2 < 1)
12077 doFault (FAULT_IPR, fst_ill_proc, "mp3d adjusted n2<1");
12078
12079 switch(e->S3)
12080 {
12081 case CSFL:
12082 n3 = (int) e->N3 - 1;
12083 if (dstTN == CTN4)
12084 n3 -= 2;
12085 else
12086 n3 -= 1;
12087 break;
12088
12089 case CSLS:
12090 case CSTS:
12091 n3 = (int) e->N3 - 1;
12092 break;
12093
12094 case CSNS:
12095 n3 = (int) e->N3;
12096 break;
12097 }
12098
12099 if (n3 < 1)
12100 doFault (FAULT_IPR, fst_ill_proc, "mp3d adjusted n3<1");
12101
12102 decContext set;
12103
12104 decContextDefaultDPS8Mul(&set);
12105
12106 set.traps=0;
12107
12108 decNumber _1, _2, _3;
12109
12110 EISloadInputBufferNumeric (cpup, 1);
12111
12112 decNumber *op1 = decBCD9ToNumber(e->inBuffer, n1, sc1, &_1);
12113 if (e->sign == -1)
12114 op1->bits |= DECNEG;
12115 if (e->S1 == CSFL)
12116 op1->exponent = e->exponent;
12117
12118 EISloadInputBufferNumeric (cpup, 2);
12119
12120 decNumber *op2 = decBCD9ToNumber(e->inBuffer, n2, sc2, &_2);
12121 if (e->sign == -1)
12122 op2->bits |= DECNEG;
12123 if (e->S2 == CSFL)
12124 op2->exponent = e->exponent;
12125
12126 decNumber *op3 = decNumberMultiply(&_3, op1, op2, &set);
12127
12128
12129
12130
12131
12132
12133
12134
12135
12136
12137
12138
12139 bool Ovr = false, EOvr = false, Trunc = false;
12140
12141 uint8_t out [256];
12142 char *res = formatDecimal(out, &set, op3, n3, (int) e->S3, e->SF3, R, &Ovr, &Trunc);
12143
12144 if (decNumberIsZero(op3))
12145 op3->exponent = 127;
12146
12147
12148
12149
12150 int pos = (int) dstCN;
12151
12152
12153 switch(e->S3)
12154 {
12155 case CSFL:
12156 case CSLS:
12157 switch(dstTN)
12158 {
12159 case CTN4:
12160 if (e->P)
12161
12162
12163
12164 EISwrite49(cpup, &e->ADDR3, &pos, (int) dstTN,
12165 (decNumberIsNegative(op3) && !decNumberIsZero(op3)) ? 015 : 013);
12166 else
12167 EISwrite49(cpup, &e->ADDR3, &pos, (int) dstTN,
12168 (decNumberIsNegative(op3) && !decNumberIsZero(op3)) ? 015 : 014);
12169 break;
12170 case CTN9:
12171 EISwrite49(cpup, &e->ADDR3, &pos, (int) dstTN,
12172 (decNumberIsNegative(op3) && !decNumberIsZero(op3)) ? '-' : '+');
12173 break;
12174 }
12175 break;
12176
12177 case CSTS:
12178 case CSNS:
12179 break;
12180 }
12181
12182
12183 for(int i = 0 ; i < n3 ; i++)
12184 switch(dstTN)
12185 {
12186 case CTN4:
12187 EISwrite49(cpup, &e->ADDR3, &pos, (int) dstTN, (word9) (res[i] - '0'));
12188 break;
12189 case CTN9:
12190 EISwrite49(cpup, &e->ADDR3, &pos, (int) dstTN, (word9) res[i]);
12191 break;
12192 }
12193
12194
12195 switch(e->S3)
12196 {
12197 case CSTS:
12198 switch(dstTN)
12199 {
12200 case CTN4:
12201 if (e->P)
12202
12203
12204 EISwrite49(cpup, &e->ADDR3, &pos, (int) dstTN,
12205 (decNumberIsNegative(op3) && !decNumberIsZero(op3)) ? 015 : 013);
12206 else
12207 EISwrite49(cpup, &e->ADDR3, &pos, (int) dstTN,
12208 (decNumberIsNegative(op3) && !decNumberIsZero(op3)) ? 015 : 014);
12209 break;
12210 case CTN9:
12211 EISwrite49(cpup, &e->ADDR3, &pos, (int) dstTN,
12212 (decNumberIsNegative(op3) && !decNumberIsZero(op3)) ? '-' : '+');
12213 break;
12214 }
12215 break;
12216
12217 case CSFL:
12218
12219 switch(dstTN)
12220 {
12221 case CTN4:
12222 EISwrite49(cpup, &e->ADDR3, &pos, (int) dstTN, (op3->exponent >> 4) & 0xf);
12223 EISwrite49(cpup, &e->ADDR3, &pos, (int) dstTN, op3->exponent & 0xf);
12224 break;
12225 case CTN9:
12226 EISwrite49(cpup, &e->ADDR3, &pos, (int) dstTN, op3->exponent & 0xff);
12227 break;
12228 }
12229 break;
12230
12231 case CSLS:
12232 case CSNS:
12233 break;
12234 }
12235
12236
12237 if (e->S3 == CSFL)
12238 {
12239 if (op3->exponent > 127)
12240 {
12241 SET_I_EOFL;
12242 EOvr = true;
12243 }
12244 if (op3->exponent < -128)
12245 {
12246 SET_I_EUFL;
12247 EOvr = true;
12248 }
12249 }
12250
12251 SC_I_NEG (decNumberIsNegative(op3) && !decNumberIsZero(op3));
12252 SC_I_ZERO (decNumberIsZero(op3));
12253
12254 SC_I_TRUNC (!R && Trunc);
12255
12256 cleanupOperandDescriptor (cpup, 1);
12257 cleanupOperandDescriptor (cpup, 2);
12258 cleanupOperandDescriptor (cpup, 3);
12259
12260 if (TST_I_TRUNC && T && tstOVFfault (cpup))
12261 doFault(FAULT_OFL, fst_zero, "mp3d truncation(overflow) fault");
12262 if (EOvr && tstOVFfault (cpup))
12263 doFault(FAULT_OFL, fst_zero, "mp3d over/underflow fault");
12264 if (Ovr)
12265 {
12266 SET_I_OFLOW;
12267 if (tstOVFfault (cpup))
12268 doFault(FAULT_OFL, fst_zero, "mp3d overflow fault");
12269 }
12270 }
12271
12272
12273
12274
12275
12276
12277
12278
12279
12280
12281
12282
12283
12284
12285
12286
12287
12288
12289
12290
12291
12292
12293
12294
12295
12296
12297
12298
12299
12300
12301
12302
12303
12304
12305
12306
12307
12308
12309
12310
12311
12312
12313
12314
12315
12316
12317
12318
12319
12320
12321
12322
12323
12324
12325
12326
12327
12328
12329
12330
12331
12332
12333
12334
12335
12336
12337
12338
12339
12340
12341
12342
12343
12344
12345
12346
12347
12348
12349
12350
12351
12352
12353
12354
12355
12356
12357
12358
12359
12360
12361
12362
12363
12364
12365
12366
12367
12368
12369
12370
12371
12372
12373
12374
12375
12376
12377
12378
12379
12380
12381
12382
12383
12384
12385
12386
12387
12388
12389
12390
12391
12392
12393
12394
12395
12396
12397
12398
12399
12400
12401
12402
12403
12404
12405
12406
12407
12408
12409
12410
12411
12412
12413
12414
12415
12416
12417
12418
12419
12420
12421
12422
12423
12424
12425
12426
12427
12428
12429
12430
12431
12432
12433
12434
12435
12436
12437
12438
12439
12440
12441
12442
12443
12444
12445
12446
12447
12448
12449
12450
12451
12452
12453
12454
12455
12456
12457
12458
12459
12460
12461
12462
12463
12464
12465
12466
12467
12468
12469
12470
12471
12472
12473
12474
12475
12476
12477
12478
12479
12480
12481
12482
12483
12484
12485
12486
12487
12488
12489
12490
12491
12492
12493
12494
12495
12496
12497
12498
12499
12500
12501
12502
12503
12504
12505
12506
12507
12508
12509
12510
12511
12512
12513
12514
12515
12516
12517
12518
12519
12520
12521
12522
12523
12524
12525
12526
12527
12528
12529
12530
12531
12532
12533
12534
12535
12536
12537
12538
12539
12540
12541
12542
12543
12544
12545
12546
12547
12548
12549
12550
12551
12552
12553
12554
12555
12556
12557
12558
12559
12560
12561
12562
12563
12564
12565
12566
12567
12568
12569
12570
12571
12572
12573
12574
12575
12576
12577
12578
12579
12580
12581
12582
12583
12584
12585
12586
12587
12588
12589
12590
12591
12592
12593
12594
12595
12596
12597
12598
12599
12600
12601
12602
12603
12604
12605
12606
12607
12608
12609
12610
12611
12612
12613
12614
12615
12616
12617
12618
12619
12620
12621
12622
12623
12624
12625
12626
12627
12628
12629
12630
12631
12632
12633
12634
12635
12636
12637
12638
12639
12640
12641
12642
12643
12644
12645
12646
12647
12648
12649
12650
12651
12652
12653
12654
12655
12656
12657
12658
12659
12660
12661
12662
12663
12664
12665
12666
12667
12668
12669
12670
12671
12672
12673
12674
12675
12676
12677
12678
12679
12680
12681
12682
12683
12684
12685
12686
12687
12688
12689
12690
12691
12692
12693
12694
12695
12696
12697
12698
12699
12700
12701
12702
12703
12704
12705
12706
12707
12708
12709
12710
12711
12712
12713
12714
12715
12716
12717
12718
12719
12720
12721
12722
12723
12724
12725
12726
12727
12728
12729
12730
12731
12732
12733
12734
12735
12736
12737
12738
12739
12740
12741
12742
12743
12744
12745
12746
12747
12748
12749
12750
12751
12752
12753
12754
12755
12756
12757
12758
12759
12760
12761
12762
12763
12764
12765
12766
12767
12768
12769
12770
12771
12772
12773
12774
12775
12776
12777
12778
12779
12780
12781
12782
12783
12784
12785
12786
12787
12788
12789
12790
12791
12792
12793
12794
12795
12796
12797
12798
12799
12800
12801
12802
12803
12804
12805
12806
12807
12808
12809
12810
12811
12812
12813
12814
12815
12816
12817
12818
12819
12820
12821
12822
12823
12824
12825
12826
12827
12828
12829
12830
12831
12832
12833
12834
12835
12836
12837
12838
12839
12840
12841
12842
12843
12844
12845
12846
12847
12848
12849
12850
12851
12852
12853
12854
12855
12856
12857
12858
12859
12860
12861
12862
12863
12864
12865
12866
12867
12868
12869
12870
12871
12872
12873
12874
12875
12876
12877
12878
12879
12880
12881
12882
12883
12884
12885
12886
12887
12888
12889
12890
12891
12892
12893
12894
12895
12896
12897
12898
12899
12900
12901
12902
12903
12904
12905
12906
12907
12908
12909
12910
12911
12912
12913
12914
12915
12916
12917
12918
12919
12920
12921
12922
12923
12924
12925
12926
12927
12928
12929
12930
12931
12932
12933
12934
12935
12936
12937
12938
12939
12940
12941
12942
12943
12944
12945
12946
12947
12948
12949
12950
12951
12952
12953
12954
12955
12956
12957
12958
12959
12960
12961
12962
12963
12964
12965
12966
12967
12968
12969
12970
12971
12972
12973
12974
12975
12976
12977
12978
12979
12980
12981
12982
12983
12984
12985
12986
12987
12988
12989
12990
12991
12992
12993
12994
12995
12996
12997
12998
12999
13000
13001
13002
13003
13004
13005
13006
13007
13008
13009
13010
13011
13012
13013
13014
13015
13016
13017
13018
13019
13020
13021
13022
13023
13024
13025 void dv2d (cpu_state_t * cpup)
13026 {
13027 EISstruct * e = & cpu.currentEISinstruction;
13028
13029 fault_ipr_subtype_ mod_fault = 0;
13030
13031 #if !defined(EIS_SETUP)
13032 setupOperandDescriptor(cpup, 1, &mod_fault);
13033 setupOperandDescriptor(cpup, 2, &mod_fault);
13034 setupOperandDescriptorCache(cpup, 3);
13035 #endif
13036
13037 parseNumericOperandDescriptor(cpup, 1, &mod_fault);
13038 parseNumericOperandDescriptor(cpup, 2, &mod_fault);
13039
13040 L68_ (
13041
13042 if (mod_fault)
13043 {
13044 doFault (FAULT_IPR,
13045 (_fault_subtype) {.fault_ipr_subtype=mod_fault},
13046 "Illegal modifier");
13047 }
13048 )
13049
13050
13051
13052 if (IWB_IRODD & 0377400000000)
13053 doFault (FAULT_IPR, (_fault_subtype) {.fault_ipr_subtype=FR_ILL_OP|mod_fault}, "dv2d 1-9 MBZ");
13054
13055 DPS8M_ (
13056
13057 if (mod_fault)
13058 {
13059 doFault (FAULT_IPR,
13060 (_fault_subtype) {.fault_ipr_subtype=mod_fault},
13061 "Illegal modifier");
13062 }
13063 )
13064
13065 e->P = getbits36_1 (cpu.cu.IWB, 0) != 0;
13066
13067 bool R = getbits36_1 (cpu.cu.IWB, 10) != 0;
13068
13069 PNL (L68_ (if (R)
13070 DU_CYCLE_FRND;))
13071
13072 uint srcTN = e->TN1;
13073
13074 uint dstTN = e->TN2;
13075 uint dstCN = e->CN2;
13076
13077 e->ADDR3 = e->ADDR2;
13078
13079 int n1 = 0, n2 = 0, sc1 = 0, sc2 = 0;
13080
13081
13082
13083
13084
13085
13086
13087
13088
13089
13090
13091 switch(e->S1)
13092 {
13093 case CSFL:
13094 n1 = (int) e->N1 - 1;
13095 if (srcTN == CTN4)
13096 n1 -= 2;
13097 else
13098 n1 -= 1;
13099 sc1 = 0;
13100 break;
13101
13102 case CSLS:
13103 case CSTS:
13104 n1 = (int) e->N1 - 1;
13105 sc1 = -e->SF1;
13106 break;
13107
13108 case CSNS:
13109 n1 = (int) e->N1;
13110 sc1 = -e->SF1;
13111 break;
13112 }
13113
13114 if (n1 < 1)
13115 doFault (FAULT_IPR, fst_ill_proc, "dv2d adjusted n1<1");
13116
13117 switch(e->S2)
13118 {
13119 case CSFL:
13120 n2 = (int) e->N2 - 1;
13121 if (e->TN2 == CTN4)
13122 n2 -= 2;
13123 else
13124 n2 -= 1;
13125 sc2 = 0;
13126 break;
13127
13128 case CSLS:
13129 case CSTS:
13130 n2 = (int) e->N2 - 1;
13131 sc2 = -e->SF2;
13132 break;
13133
13134 case CSNS:
13135 n2 = (int) e->N2;
13136 sc2 = -e->SF2;
13137 break;
13138 }
13139
13140 if (n2 < 1)
13141 doFault (FAULT_IPR, fst_ill_proc, "dv2d adjusted n2<1");
13142
13143 decContext set;
13144 decContextDefaultDPS8(&set);
13145
13146 set.traps=0;
13147
13148 decNumber _1, _2, _3;
13149
13150 EISloadInputBufferNumeric (cpup, 1);
13151
13152 decNumber *op1 = decBCD9ToNumber(e->inBuffer, n1, sc1, &_1);
13153 if (e->sign == -1)
13154 op1->bits |= DECNEG;
13155 if (e->S1 == CSFL)
13156 op1->exponent = e->exponent;
13157
13158
13159 if (decNumberIsZero(op1))
13160 {
13161 doFault(FAULT_DIV, fst_zero, "dv2d division by 0");
13162 }
13163
13164 word9 inBufferop1 [64];
13165 memcpy (inBufferop1,e->inBuffer,sizeof(inBufferop1));
13166
13167 EISloadInputBufferNumeric (cpup, 2);
13168
13169 decNumber *op2 = decBCD9ToNumber(e->inBuffer, n2, sc2, &_2);
13170 if (e->sign == -1)
13171 op2->bits |= DECNEG;
13172 if (e->S2 == CSFL)
13173 op2->exponent = e->exponent;
13174
13175 int NQ;
13176 if (e->S2 == CSFL)
13177 {
13178 NQ = n2;
13179 }
13180 else
13181 {
13182
13183
13184 int clz1, clz2, i;
13185 for (i=0; i < op1->digits; i++)
13186 if (inBufferop1[i]!=0)
13187 break;
13188 clz1 = i;
13189 for (i=0; i < op2->digits; i++)
13190 if (e->inBuffer[i]!=0)
13191 break;
13192 clz2 = i;
13193 sim_debug (DBG_TRACEEXT, & cpu_dev, "dv2d: clz1 %d clz2 %d\r\n",clz1,clz2);
13194
13195
13196
13197 NQ = (n2-clz2+1) - (n1-clz1) + (-(e->S1==CSFL?op1->exponent:(int)e->SF1));
13198
13199 sim_debug (DBG_TRACEEXT, & cpu_dev, "dv2d S1 %d S2 %d N1 %d N2 %d clz1 %d clz2 %d E1 %d E2 %d SF2 %d NQ %d\r\n",
13200 e->S1,e->S2,e->N1,e->N2,clz1,clz2,op1->exponent,op2->exponent,e->SF2,NQ);
13201 }
13202 if (NQ > 63)
13203 doFault(FAULT_DIV, fst_zero, "dv2d NQ>63");
13204
13205
13206
13207
13208 decNumber *op3 = decNumberDivide(&_3, op2, op1, &set);
13209
13210
13211
13212
13213 PRINTDEC("op2", op2);
13214 PRINTDEC("op1", op1);
13215 PRINTDEC("op3", op3);
13216
13217
13218 if (
13219 (set.status & DEC_Division_undefined) ||
13220 (set.status & DEC_Invalid_operation) ||
13221 (set.status & DEC_Division_by_zero)
13222 ) { sim_debug (DBG_TRACEEXT, & cpu_dev, "oops! dv2d anomalous results"); }
13223
13224 if (e->S2 == CSFL)
13225 {
13226
13227
13228
13229
13230
13231 decNumber _sf;
13232
13233 if (n2 - op3->digits > 0)
13234 {
13235 decNumberFromInt32(&_sf, op3->exponent - (n2 - op3->digits));
13236 PRINTDEC("Value 1", op3)
13237 PRINTDEC("Value sf", &_sf)
13238 op3 = decNumberRescale(op3, op3, &_sf, &set);
13239 PRINTDEC("Value 2", op3)
13240 }
13241 }
13242
13243 bool Ovr = false, EOvr = false, Trunc = false;
13244 uint8_t out[256];
13245
13246
13247
13248
13249
13250
13251
13252
13253
13254
13255 char *res;
13256 if (e->S2 == CSFL) {
13257 decNumber _1a;
13258 decNumber _2a;
13259 decNumber _sf;
13260 if (op1->digits >= op2->digits) {
13261
13262 decNumberCopy(&_1a, op1);
13263 decNumberFromInt32(&_sf, op1->digits - op2->digits);
13264 decNumberShift(&_2a, op2, &_sf, &set);
13265 } else if (op1->digits < op2->digits) {
13266
13267 decNumberFromInt32(&_sf, op2->digits - op1->digits);
13268 decNumberShift(&_1a, op1, &_sf, &set);
13269 decNumberCopy(&_2a, op2);
13270 }
13271 _1a.exponent = 0;
13272 _2a.exponent = 0;
13273
13274 PRINTDEC("dv2d: op1a", &_1a);
13275 PRINTDEC("dv2d: op2a", &_2a);
13276 sim_debug (DBG_TRACEEXT, & cpu_dev, "dv2d: exp1 %d exp2 %d digits op1 %d op2 %d op1a %d op2a %d\r\n",
13277 op1->exponent,op2->exponent,op1->digits,op2->digits,_1a.digits,_2a.digits);
13278
13279 if (decCompareMAG(&_1a, &_2a, &set) > 0) {
13280
13281 res = formatDecimal(out, &set, op3, n2 -1, (int) e->S2, e->SF2, R, &Ovr, &Trunc);
13282
13283
13284
13285 for (int i = n2; i > 0; i--)
13286 res[i] = res[i-1];
13287 res[0] = '0';
13288 sim_debug (DBG_TRACEEXT, & cpu_dev, "dv2d: addzero n2 %d %s exp %d\r\n",n2,res,op3->exponent);
13289 } else {
13290
13291 res = formatDecimal(out, &set, op3, n2, (int) e->S2, e->SF2, R, &Ovr, &Trunc);
13292 }
13293 } else {
13294
13295 res = formatDecimal(out, &set, op3, n2, (int) e->S2, e->SF2, R, &Ovr, &Trunc);
13296 }
13297
13298 if (decNumberIsZero(op3))
13299 op3->exponent = 127;
13300
13301
13302
13303 int pos = (int) dstCN;
13304
13305
13306 switch(e->S2)
13307 {
13308 case CSFL:
13309 case CSLS:
13310 switch(dstTN)
13311 {
13312 case CTN4:
13313 if (e->P)
13314
13315
13316 EISwrite49(cpup, &e->ADDR3, &pos, (int) dstTN,
13317 (decNumberIsNegative(op3) && !decNumberIsZero(op3)) ? 015 : 013);
13318 else
13319 EISwrite49(cpup, &e->ADDR3, &pos, (int) dstTN,
13320 (decNumberIsNegative(op3) && !decNumberIsZero(op3)) ? 015 : 014);
13321 break;
13322 case CTN9:
13323 EISwrite49(cpup, &e->ADDR3, &pos, (int) dstTN,
13324 (decNumberIsNegative(op3) && !decNumberIsZero(op3)) ? '-' : '+');
13325 break;
13326 }
13327 break;
13328
13329 case CSTS:
13330 case CSNS:
13331 break;
13332 }
13333
13334
13335 for(int i = 0 ; i < n2 ; i++)
13336 switch(dstTN)
13337 {
13338 case CTN4:
13339 EISwrite49(cpup, &e->ADDR3, &pos, (int) dstTN, (word9) (res[i] - '0'));
13340 break;
13341 case CTN9:
13342 EISwrite49(cpup, &e->ADDR3, &pos, (int) dstTN, (word9) res[i]);
13343 break;
13344 }
13345
13346
13347 switch(e->S2)
13348 {
13349 case CSTS:
13350 switch(dstTN)
13351 {
13352 case CTN4:
13353 if (e->P)
13354
13355
13356 EISwrite49(cpup, &e->ADDR3, &pos, (int) dstTN,
13357 (decNumberIsNegative(op3) && !decNumberIsZero(op3)) ? 015 : 013);
13358 else
13359 EISwrite49(cpup, &e->ADDR3, &pos, (int) dstTN,
13360 (decNumberIsNegative(op3) && !decNumberIsZero(op3)) ? 015 : 014);
13361 break;
13362 case CTN9:
13363 EISwrite49(cpup, &e->ADDR3, &pos, (int) dstTN,
13364 (decNumberIsNegative(op3) && !decNumberIsZero(op3)) ? '-' : '+');
13365 break;
13366 }
13367 break;
13368
13369 case CSFL:
13370
13371 switch(dstTN)
13372 {
13373 case CTN4:
13374 EISwrite49(cpup, &e->ADDR3, &pos, (int) dstTN, (op3->exponent >> 4) & 0xf);
13375 EISwrite49(cpup, &e->ADDR3, &pos, (int) dstTN, op3->exponent & 0xf);
13376 break;
13377 case CTN9:
13378 EISwrite49(cpup, &e->ADDR3, &pos, (int) dstTN, op3->exponent & 0xff);
13379 break;
13380 }
13381 break;
13382
13383 case CSLS:
13384 case CSNS:
13385 break;
13386 }
13387
13388
13389 if (e->S2 == CSFL)
13390 {
13391 if (op3->exponent > 127)
13392 {
13393 SET_I_EOFL;
13394 EOvr = true;
13395 }
13396 if (op3->exponent < -128)
13397 {
13398 SET_I_EUFL;
13399 EOvr = true;
13400 }
13401 }
13402
13403 SC_I_NEG (decNumberIsNegative(op3) && !decNumberIsZero(op3));
13404 SC_I_ZERO (decNumberIsZero(op3));
13405
13406
13407
13408 cleanupOperandDescriptor (cpup, 1);
13409 cleanupOperandDescriptor (cpup, 2);
13410 cleanupOperandDescriptor (cpup, 3);
13411
13412
13413
13414 if (EOvr && tstOVFfault (cpup))
13415 doFault(FAULT_OFL, fst_zero, "dv2d over/underflow fault");
13416 if (Ovr)
13417 {
13418 SET_I_OFLOW;
13419 if (tstOVFfault (cpup))
13420 doFault(FAULT_OFL, fst_zero, "dv2d overflow fault");
13421 }
13422 }
13423
13424
13425
13426
13427
13428 void dv3d (cpu_state_t * cpup)
13429
13430 {
13431 EISstruct * e = & cpu.currentEISinstruction;
13432
13433 fault_ipr_subtype_ mod_fault = 0;
13434
13435 #if !defined(EIS_SETUP)
13436 setupOperandDescriptor(cpup, 1, &mod_fault);
13437 setupOperandDescriptor(cpup, 2, &mod_fault);
13438 setupOperandDescriptor(cpup, 3, &mod_fault);
13439 #endif
13440
13441 parseNumericOperandDescriptor(cpup, 1, &mod_fault);
13442 parseNumericOperandDescriptor(cpup, 2, &mod_fault);
13443 parseNumericOperandDescriptor(cpup, 3, &mod_fault);
13444
13445 L68_ (
13446
13447 if (mod_fault)
13448 {
13449 doFault (FAULT_IPR,
13450 (_fault_subtype) {.fault_ipr_subtype=mod_fault},
13451 "Illegal modifier");
13452 }
13453 )
13454
13455
13456
13457 if (IWB_IRODD & 0200400000000)
13458 doFault (FAULT_IPR, (_fault_subtype) {.fault_ipr_subtype=FR_ILL_OP|mod_fault}, "dv3d(): 1,9 MBZ");
13459
13460 DPS8M_ (
13461
13462 if (mod_fault)
13463 {
13464 doFault (FAULT_IPR,
13465 (_fault_subtype) {.fault_ipr_subtype=mod_fault},
13466 "Illegal modifier");
13467 }
13468 )
13469
13470 e->P = getbits36_1 (cpu.cu.IWB, 0) != 0;
13471
13472 bool R = getbits36_1 (cpu.cu.IWB, 10) != 0;
13473
13474 PNL (L68_ (if (R)
13475 DU_CYCLE_FRND;))
13476
13477 uint srcTN = e->TN1;
13478
13479 uint dstTN = e->TN3;
13480 uint dstCN = e->CN3;
13481
13482 int n1 = 0, n2 = 0, n3 = 0, sc1 = 0, sc2 = 0;
13483
13484
13485
13486
13487
13488
13489
13490
13491
13492
13493
13494 switch(e->S1)
13495 {
13496 case CSFL:
13497 n1 = (int) e->N1 - 1;
13498 if (srcTN == CTN4)
13499 n1 -= 2;
13500 else
13501 n1 -= 1;
13502 sc1 = 0;
13503 break;
13504
13505 case CSLS:
13506 case CSTS:
13507 n1 = (int) e->N1 - 1;
13508 sc1 = -e->SF1;
13509 break;
13510
13511 case CSNS:
13512 n1 = (int) e->N1;
13513 sc1 = -e->SF1;
13514 break;
13515 }
13516
13517 if (n1 < 1)
13518 doFault (FAULT_IPR, fst_ill_proc, "dv3d adjusted n1<1");
13519
13520 switch(e->S2)
13521 {
13522 case CSFL:
13523 n2 = (int) e->N2 - 1;
13524 if (e->TN2 == CTN4)
13525 n2 -= 2;
13526 else
13527 n2 -= 1;
13528 sc2 = 0;
13529 break;
13530
13531 case CSLS:
13532 case CSTS:
13533 n2 = (int) e->N2 - 1;
13534 sc2 = -e->SF2;
13535 break;
13536
13537 case CSNS:
13538 n2 = (int) e->N2;
13539 sc2 = -e->SF2;
13540 break;
13541 }
13542
13543 if (n2 < 1)
13544 doFault (FAULT_IPR, fst_ill_proc, "dv3d adjusted n2<1");
13545
13546 switch(e->S3)
13547 {
13548 case CSFL:
13549 n3 = (int) e->N3 - 1;
13550 if (dstTN == CTN4)
13551 n3 -= 2;
13552 else
13553 n3 -= 1;
13554 break;
13555
13556 case CSLS:
13557 case CSTS:
13558 n3 = (int) e->N3 - 1;
13559 break;
13560
13561 case CSNS:
13562 n3 = (int) e->N3;
13563 break;
13564 }
13565 if (n3 < 1)
13566 doFault (FAULT_IPR, fst_ill_proc, "dv3d adjusted n3<1");
13567
13568 decContext set;
13569 decContextDefaultDPS8(&set);
13570
13571 set.traps=0;
13572
13573 decNumber _1, _2, _3;
13574
13575 EISloadInputBufferNumeric (cpup, 1);
13576
13577 decNumber *op1 = decBCD9ToNumber(e->inBuffer, n1, sc1, &_1);
13578
13579 if (e->sign == -1)
13580 op1->bits |= DECNEG;
13581 if (e->S1 == CSFL)
13582 op1->exponent = e->exponent;
13583
13584
13585 if (decNumberIsZero(op1))
13586 {
13587 doFault(FAULT_DIV, fst_zero, "dv3d division by 0");
13588 }
13589
13590 word9 inBufferop1 [64];
13591 memcpy (inBufferop1,e->inBuffer,sizeof(inBufferop1));
13592
13593 EISloadInputBufferNumeric (cpup, 2);
13594
13595 decNumber *op2 = decBCD9ToNumber(e->inBuffer, n2, sc2, &_2);
13596 if (e->sign == -1)
13597 op2->bits |= DECNEG;
13598 if (e->S2 == CSFL)
13599 op2->exponent = e->exponent;
13600
13601
13602
13603
13604
13605
13606
13607
13608
13609
13610
13611
13612
13613
13614
13615
13616
13617 int NQ;
13618 if (e->S3 == CSFL)
13619 {
13620 NQ = n3;
13621 }
13622 else
13623 {
13624
13625
13626 int clz1, clz2, i;
13627 for (i=0; i < op1->digits; i++)
13628 if (inBufferop1[i]!=0)
13629 break;
13630 clz1 = i;
13631 for (i=0; i < op2->digits; i++)
13632 if (e->inBuffer[i]!=0)
13633 break;
13634 clz2 = i;
13635 sim_debug (DBG_TRACEEXT, & cpu_dev, "dv3d: clz1 %d clz2 %d\r\n",clz1,clz2);
13636
13637
13638
13639 NQ = (n2-clz2+1) - (n1-clz1) + \
13640 ((e->S2==CSFL?op2->exponent:(int)e->SF2)-(e->S1==CSFL?op1->exponent:(int)e->SF1)-(int)e->SF3);
13641
13642 sim_debug (DBG_TRACEEXT, & cpu_dev, "dv3d S1 %d S2 %d N1 %d N2 %d clz1 %d clz2 %d E1 %d E2 %d SF3 %d NQ %d\r\n",
13643 e->S1,e->S2,e->N1,e->N2,clz1,clz2,op1->exponent,op2->exponent,e->SF3,NQ);
13644 }
13645 if (NQ > 63)
13646 doFault(FAULT_DIV, fst_zero, "dv3d NQ>63");
13647
13648
13649
13650
13651 decNumber *op3 = decNumberDivide(&_3, op2, op1, &set);
13652
13653
13654
13655
13656 PRINTDEC("op2", op2);
13657 PRINTDEC("op1", op1);
13658 PRINTDEC("op3", op3);
13659
13660
13661 if (
13662 (set.status & DEC_Division_undefined) ||
13663 (set.status & DEC_Invalid_operation) ||
13664 (set.status & DEC_Division_by_zero)
13665 ) { sim_debug (DBG_TRACEEXT, & cpu_dev, "oops! dv3d anomalous results"); }
13666
13667 if (e->S3 == CSFL)
13668 {
13669
13670
13671
13672
13673
13674 decNumber _sf;
13675
13676 if (n3 - op3->digits > 0)
13677 {
13678 decNumberFromInt32(&_sf, op3->exponent - (n3 - op3->digits));
13679 PRINTDEC("Value 1", op3)
13680 PRINTDEC("Value sf", &_sf)
13681 op3 = decNumberRescale(op3, op3, &_sf, &set);
13682 PRINTDEC("Value 2", op3)
13683 }
13684 }
13685
13686 bool Ovr = false, EOvr = false, Trunc = false;
13687 uint8_t out[256];
13688
13689
13690
13691
13692
13693
13694
13695
13696
13697
13698 char *res;
13699 if (e->S3 == CSFL) {
13700 decNumber _1a;
13701 decNumber _2a;
13702 decNumber _sf;
13703 if (op1->digits >= op2->digits) {
13704
13705 decNumberCopy(&_1a, op1);
13706 decNumberFromInt32(&_sf, op1->digits - op2->digits);
13707 decNumberShift(&_2a, op2, &_sf, &set);
13708 } else if (op1->digits < op2->digits) {
13709
13710 decNumberFromInt32(&_sf, op2->digits - op1->digits);
13711 decNumberShift(&_1a, op1, &_sf, &set);
13712 decNumberCopy(&_2a, op2);
13713 }
13714 _1a.exponent = 0;
13715 _2a.exponent = 0;
13716
13717 PRINTDEC("dv3d: op1a", &_1a);
13718 PRINTDEC("dv3d: op2a", &_2a);
13719 sim_debug (DBG_TRACEEXT, & cpu_dev,
13720 "dv3d: exp1 %d exp2 %d digits op1 %d op2 %d op1a %d op2a %d\r\n",
13721 op1->exponent ,op2->exponent, op1->digits,
13722 op2->digits, _1a.digits, _2a.digits);
13723
13724 if (decCompareMAG(&_1a, &_2a, &set) > 0) {
13725
13726 res = formatDecimal(out, &set, op3, n3 -1, (int) e->S3, e->SF3, R, &Ovr, &Trunc);
13727
13728
13729
13730 for (int i = n3; i > 0; i--)
13731 res[i] = res[i-1];
13732 res[0] = '0';
13733 sim_debug (DBG_TRACEEXT, & cpu_dev, "dv3d: addzero n3 %d %s exp %d\r\n",n3,res,op3->exponent);
13734 } else {
13735
13736 res = formatDecimal(out, &set, op3, n3, (int) e->S3, e->SF3, R, &Ovr, &Trunc);
13737 }
13738 } else {
13739
13740 res = formatDecimal(out, &set, op3, n3, (int) e->S3, e->SF3, R, &Ovr, &Trunc);
13741 }
13742
13743 if (decNumberIsZero(op3))
13744 op3->exponent = 127;
13745
13746
13747
13748
13749
13750 int pos = (int) dstCN;
13751
13752
13753 switch(e->S3)
13754 {
13755 case CSFL:
13756 case CSLS:
13757 switch(dstTN)
13758 {
13759 case CTN4:
13760 if (e->P)
13761
13762
13763 EISwrite49(cpup, &e->ADDR3, &pos, (int) dstTN,
13764 (decNumberIsNegative(op3) && !decNumberIsZero(op3)) ? 015 : 013);
13765 else
13766 EISwrite49(cpup, &e->ADDR3, &pos, (int) dstTN,
13767 (decNumberIsNegative(op3) && !decNumberIsZero(op3)) ? 015 : 014);
13768 break;
13769 case CTN9:
13770 EISwrite49(cpup, &e->ADDR3, &pos, (int) dstTN,
13771 (decNumberIsNegative(op3) && !decNumberIsZero(op3)) ? '-' : '+');
13772 break;
13773 }
13774 break;
13775
13776 case CSTS:
13777 case CSNS:
13778 break;
13779 }
13780
13781
13782 for(int i = 0 ; i < n3 ; i++)
13783 switch(dstTN)
13784 {
13785 case CTN4:
13786 EISwrite49(cpup, &e->ADDR3, &pos, (int) dstTN, (word9) (res[i] - '0'));
13787 break;
13788 case CTN9:
13789 EISwrite49(cpup, &e->ADDR3, &pos, (int) dstTN, (word9) res[i]);
13790 break;
13791 }
13792
13793
13794 switch(e->S3)
13795 {
13796 case CSTS:
13797 switch(dstTN)
13798 {
13799 case CTN4:
13800 if (e->P)
13801
13802
13803 EISwrite49(cpup, &e->ADDR3, &pos, (int) dstTN,
13804 (decNumberIsNegative(op3) && !decNumberIsZero(op3)) ? 015 : 013);
13805 else
13806 EISwrite49(cpup, &e->ADDR3, &pos, (int) dstTN,
13807 (decNumberIsNegative(op3) && !decNumberIsZero(op3)) ? 015 : 014);
13808 break;
13809 case CTN9:
13810 EISwrite49(cpup, &e->ADDR3, &pos, (int) dstTN,
13811 (decNumberIsNegative(op3) && !decNumberIsZero(op3)) ? '-' : '+');
13812 break;
13813 }
13814 break;
13815
13816 case CSFL:
13817
13818 switch(dstTN)
13819 {
13820 case CTN4:
13821 EISwrite49(cpup, &e->ADDR3, &pos, (int) dstTN, (op3->exponent >> 4) & 0xf);
13822 EISwrite49(cpup, &e->ADDR3, &pos, (int) dstTN, op3->exponent & 0xf);
13823 break;
13824 case CTN9:
13825 EISwrite49(cpup, &e->ADDR3, &pos, (int) dstTN, op3->exponent & 0xff);
13826 break;
13827 }
13828 break;
13829
13830 case CSLS:
13831 case CSNS:
13832 break;
13833 }
13834
13835
13836 if (e->S3 == CSFL)
13837 {
13838 if (op3->exponent > 127)
13839 {
13840 SET_I_EOFL;
13841 EOvr = true;
13842 }
13843 if (op3->exponent < -128)
13844 {
13845 SET_I_EUFL;
13846 EOvr = true;
13847 }
13848 }
13849
13850 SC_I_NEG (decNumberIsNegative(op3) && !decNumberIsZero(op3));
13851 SC_I_ZERO (decNumberIsZero(op3));
13852
13853
13854
13855 cleanupOperandDescriptor (cpup, 1);
13856 cleanupOperandDescriptor (cpup, 2);
13857 cleanupOperandDescriptor (cpup, 3);
13858
13859
13860
13861 if (EOvr && tstOVFfault (cpup))
13862 doFault(FAULT_OFL, fst_zero, "dv3d over/underflow fault");
13863 if (Ovr)
13864 {
13865 SET_I_OFLOW;
13866 if (tstOVFfault (cpup))
13867 doFault(FAULT_OFL, fst_zero, "dv3d overflow fault");
13868 }
13869 }