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