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