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