This source file includes following definitions.
- selftest_ptwaw
- do_ldbr
- fetch_dsptw
- modify_dsptw
- calc_hit_am
- fetch_sdw_from_sdwam
- fetch_psdw
- fetch_nsdw
- str_sdw
- dump_sdwam
- to_be_discarded_am
- load_sdwam
- fetch_ptw_from_ptwam
- fetch_ptw
- loadPTWAM
- modify_ptw
- do_ptw2
- str_access_type
- str_acv
- str_pct
- do_append_cycle
- do_append_cycle
- dbgLookupAddress
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33 #include <stdio.h>
34 #include "dps8.h"
35 #include "dps8_sys.h"
36 #include "dps8_faults.h"
37 #include "dps8_scu.h"
38 #include "dps8_iom.h"
39 #include "dps8_cable.h"
40 #include "dps8_cpu.h"
41 #include "dps8_append.h"
42 #include "dps8_addrmods.h"
43 #include "dps8_utils.h"
44 #if defined(THREADZ) || defined(LOCKLESS)
45 # include "threadz.h"
46 #endif
47
48 #define DBG_CTR cpu.cycleCnt
49
50
51
52
53
54 #ifdef TESTING
55 # define DBG_CTR cpu.cycleCnt
56 # define DBGAPP(...) sim_debug (DBG_APPENDING, & cpu_dev, __VA_ARGS__)
57 #else
58 # define DBGAPP(...)
59 #endif
60
61
62
63
64
65
66
67
68
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
112
113
114
115
116
117 #ifdef TESTING
118 static char *str_sdw (char * buf, sdw_s *SDW);
119 #endif
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141 #ifdef do_selftestPTWAM
142 static void selftest_ptwaw (void)
143 {
144 int usages[N_NAX_WAM_ENTRIES];
145 for (int i = 0; i < N_MODEL_WAM_ENTRIES; i ++)
146 usages[i] = -1;
147
148 for (int i = 0; i < N_MODEL_WAM_ENTRIES; i ++)
149 {
150 ptw_s * p = cpu.PTWAM + i;
151 if (p->USE > N_MODEL_WAM_ENTRIES - 1)
152 sim_printf ("PTWAM[%d].USE is %d; > %d!\n",
153 i, p->USE, N_MODEL_WAM_ENTRIES - 1);
154 if (usages[p->USE] != -1)
155 sim_printf ("PTWAM[%d].USE is equal to PTWAM[%d].USE; %d\n",
156 i, usages[p->USE], p->USE);
157 usages[p->USE] = i;
158 }
159 for (int i = 0; i < N_MODEL_WAM_ENTRIES; i ++)
160 {
161 if (usages[i] == -1)
162 sim_printf ("No PTWAM had a USE of %d\n", i);
163 }
164 }
165 #endif
166
167
168
169
170
171 void do_ldbr (word36 * Ypair)
172 {
173 CPTUR (cptUseDSBR);
174 if (cpu.tweaks.enable_wam)
175 {
176 if (cpu.cu.SD_ON)
177 {
178
179
180
181 for (uint i = 0; i < N_MODEL_WAM_ENTRIES; i ++)
182 {
183 cpu.SDWAM[i].FE = 0;
184 L68_ (cpu.SDWAM[i].USE = (word4) i;)
185 DPS8M_ (cpu.SDWAM[i].USE = 0;)
186 }
187 }
188
189 if (cpu.cu.PT_ON)
190 {
191
192
193
194 for (uint i = 0; i < N_MODEL_WAM_ENTRIES; i ++)
195 {
196 cpu.PTWAM[i].FE = 0;
197 L68_ (cpu.PTWAM[i].USE = (word4) i;)
198 DPS8M_ (cpu.PTWAM[i].USE = 0;)
199 }
200 #ifdef do_selftestPTWAM
201 selftest_ptwaw ();
202 #endif
203 }
204 }
205 else
206 {
207 cpu.SDW0.FE = 0;
208 cpu.SDW0.USE = 0;
209 cpu.PTW0.FE = 0;
210 cpu.PTW0.USE = 0;
211 }
212
213
214
215
216
217 cpu.DSBR.ADDR = (Ypair[0] >> (35 - 23)) & PAMASK;
218
219
220 cpu.DSBR.BND = (Ypair[1] >> (71 - 50)) & 037777;
221
222
223 cpu.DSBR.U = (Ypair[1] >> (71 - 55)) & 01;
224
225
226 cpu.DSBR.STACK = (Ypair[1] >> (71 - 71)) & 07777;
227 DBGAPP ("ldbr 0 -> SDWAM/PTWAM[*].F, i -> SDWAM/PTWAM[i].USE, "
228 "DSBR.ADDR 0%o, DSBR.BND 0%o, DSBR.U 0%o, DSBR.STACK 0%o\n",
229 cpu.DSBR.ADDR, cpu.DSBR.BND, cpu.DSBR.U, cpu.DSBR.STACK);
230 }
231
232
233
234
235
236
237
238 static void fetch_dsptw (word15 segno)
239 {
240 DBGAPP ("%s segno 0%o\n", __func__, segno);
241 PNL (L68_ (cpu.apu.state |= apu_FDPT;))
242
243 if (2 * segno >= 16 * (cpu.DSBR.BND + 1))
244 {
245 DBGAPP ("%s ACV15\n", __func__);
246
247 PNL (cpu.acvFaults |= ACV15;)
248 PNL (L68_ (cpu.apu.state |= apu_FLT;))
249 doFault (FAULT_ACV, fst_acv15,
250 "acvFault: fetch_dsptw out of segment bounds fault");
251 }
252 set_apu_status (apuStatus_DSPTW);
253
254
255 word24 x1 = (2u * segno) / 1024u;
256
257 PNL (cpu.lastPTWOffset = segno;)
258 PNL (cpu.lastPTWIsDS = true;)
259
260 word36 PTWx1;
261 core_read ((cpu.DSBR.ADDR + x1) & PAMASK, & PTWx1, __func__);
262
263 cpu.PTW0.ADDR = GETHI (PTWx1);
264 cpu.PTW0.U = TSTBIT (PTWx1, 9);
265 cpu.PTW0.M = TSTBIT (PTWx1, 6);
266 cpu.PTW0.DF = TSTBIT (PTWx1, 2);
267 cpu.PTW0.FC = PTWx1 & 3;
268
269 L68_ (if (cpu.MR_cache.emr && cpu.MR_cache.ihr)
270 add_l68_APU_history (APUH_FDSPTW);)
271
272 DBGAPP ("%s x1 0%o DSBR.ADDR 0%o PTWx1 0%012"PRIo64" "
273 "PTW0: ADDR 0%o U %o M %o F %o FC %o\n",
274 __func__, x1, cpu.DSBR.ADDR, PTWx1, cpu.PTW0.ADDR, cpu.PTW0.U,
275 cpu.PTW0.M, cpu.PTW0.DF, cpu.PTW0.FC);
276 }
277
278
279
280
281
282
283
284 static void modify_dsptw (word15 segno)
285 {
286
287 PNL (L68_ (cpu.apu.state |= apu_MDPT;))
288
289 set_apu_status (apuStatus_MDSPTW);
290
291 word24 x1 = (2u * segno) / 1024u;
292
293 #ifdef THREADZ
294 bool lck = get_rmw_lock ();
295 if (! lck)
296 lock_rmw ();
297 #endif
298
299 word36 PTWx1;
300 #ifdef LOCKLESS
301 core_read_lock ((cpu.DSBR.ADDR + x1) & PAMASK, & PTWx1, __func__);
302 PTWx1 = SETBIT (PTWx1, 9);
303 core_write_unlock ((cpu.DSBR.ADDR + x1) & PAMASK, PTWx1, __func__);
304 #else
305 core_read ((cpu.DSBR.ADDR + x1) & PAMASK, & PTWx1, __func__);
306 PTWx1 = SETBIT (PTWx1, 9);
307 core_write ((cpu.DSBR.ADDR + x1) & PAMASK, PTWx1, __func__);
308 #endif
309
310 #ifdef THREADZ
311 if (! lck)
312 unlock_rmw ();
313 #endif
314
315 cpu.PTW0.U = 1;
316 L68_ (if (cpu.MR_cache.emr && cpu.MR_cache.ihr)
317 add_l68_APU_history (APUH_MDSPTW);)
318 }
319
320 static word6 calc_hit_am (word6 LRU, uint hit_level)
321 {
322 switch (hit_level)
323 {
324 case 0:
325 return (LRU | 070);
326 case 1:
327 return ((LRU & 037) | 06);
328 case 2:
329 return ((LRU & 053) | 01);
330 case 3:
331 return (LRU & 064);
332 default:
333 DBGAPP ("%s: Invalid AM level\n", __func__);
334 return 0;
335 }
336 }
337
338 static sdw_s * fetch_sdw_from_sdwam (word15 segno) {
339 DBGAPP ("%s(0):segno=%05o\n", __func__, segno);
340
341 if ((! cpu.tweaks.enable_wam || ! cpu.cu.SD_ON)) {
342 DBGAPP ("%s(0): SDWAM disabled\n", __func__);
343 return NULL;
344 }
345
346 if (cpu.tweaks.l68_mode) {
347 int nwam = N_L68_WAM_ENTRIES;
348 for (int _n = 0; _n < nwam; _n++) {
349
350 if (cpu.SDWAM[_n].FE && segno == cpu.SDWAM[_n].POINTER) {
351 DBGAPP ("%s(1):found match for segno %05o " "at _n=%d\n", __func__, segno, _n);
352
353 cpu.cu.SDWAMM = 1;
354 cpu.SDWAMR = (word4) _n;
355 cpu.SDW = & cpu.SDWAM[_n];
356
357
358
359
360
361
362
363 for (int _h = 0; _h < nwam; _h++) {
364 if (cpu.SDWAM[_h].USE > cpu.SDW->USE)
365 cpu.SDWAM[_h].USE -= 1;
366 }
367 cpu.SDW->USE = N_L68_WAM_ENTRIES - 1;
368
369 char buf[256];
370 (void)buf;
371 #ifdef TESTING
372 DBGAPP ("%s(2):SDWAM[%d]=%s\n", __func__, _n, str_sdw (buf, cpu.SDW));
373 #endif
374 return cpu.SDW;
375 }
376 }
377 }
378
379 if (! cpu.tweaks.l68_mode) {
380 uint setno = segno & 017;
381 uint toffset;
382 sdw_s *p;
383 for (toffset = 0; toffset < 64; toffset += 16) {
384 p = & cpu.SDWAM[toffset + setno];
385 if (p->FE && segno == p->POINTER) {
386 DBGAPP ("%s(1):found match for segno %05o " "at _n=%d\n", __func__, segno, toffset + setno);
387
388 cpu.cu.SDWAMM = 1;
389 cpu.SDWAMR = (word6) (toffset + setno);
390 cpu.SDW = p;
391
392 word6 u = calc_hit_am (p->USE, toffset >> 4);
393 for (toffset = 0; toffset < 64; toffset += 16) {
394 p = & cpu.SDWAM[toffset + setno];
395 if (p->FE)
396 p->USE = u;
397 }
398
399 char buf[256];
400 (void)buf;
401 #ifdef TESTING
402 DBGAPP ("%s(2):SDWAM[%d]=%s\n", __func__, toffset + setno, str_sdw (buf, cpu.SDW));
403 #endif
404 return cpu.SDW;
405 }
406 }
407 }
408 #ifdef TESTING
409 DBGAPP ("%s(3):SDW for segment %05o not found in SDWAM\n", __func__, segno);
410 #endif
411 cpu.cu.SDWAMM = 0;
412 return NULL;
413 }
414
415
416
417
418
419
420 static void fetch_psdw (word15 segno)
421 {
422 DBGAPP ("%s(0):segno=%05o\n",
423 __func__, segno);
424
425 PNL (L68_ (cpu.apu.state |= apu_FSDP;))
426
427 set_apu_status (apuStatus_SDWP);
428 word24 y1 = (2 * segno) % 1024;
429
430 word36 SDWeven, SDWodd;
431
432 core_read2 (((((word24) cpu.PTW0.ADDR & 0777760) << 6) + y1) & PAMASK,
433 & SDWeven, & SDWodd, __func__);
434
435
436 cpu.SDW0.ADDR = (SDWeven >> 12) & 077777777;
437 cpu.SDW0.R1 = (SDWeven >> 9) & 7;
438 cpu.SDW0.R2 = (SDWeven >> 6) & 7;
439 cpu.SDW0.R3 = (SDWeven >> 3) & 7;
440 cpu.SDW0.DF = TSTBIT (SDWeven, 2);
441 cpu.SDW0.FC = SDWeven & 3;
442
443
444 cpu.SDW0.BOUND = (SDWodd >> 21) & 037777;
445 cpu.SDW0.R = TSTBIT (SDWodd, 20);
446 cpu.SDW0.E = TSTBIT (SDWodd, 19);
447 cpu.SDW0.W = TSTBIT (SDWodd, 18);
448 cpu.SDW0.P = TSTBIT (SDWodd, 17);
449 cpu.SDW0.U = TSTBIT (SDWodd, 16);
450 cpu.SDW0.G = TSTBIT (SDWodd, 15);
451 cpu.SDW0.C = TSTBIT (SDWodd, 14);
452 cpu.SDW0.EB = SDWodd & 037777;
453
454 L68_ (
455 if (cpu.MR_cache.emr && cpu.MR_cache.ihr)
456 add_l68_APU_history (APUH_FSDWP);
457 )
458 DBGAPP ("%s y1 0%o p->ADDR 0%o SDW 0%012"PRIo64" 0%012"PRIo64" "
459 "ADDR %o R %o%o%o BOUND 0%o REWPUGC %o%o%o%o%o%o%o "
460 "F %o FC %o FE %o USE %o\n",
461 __func__, y1, cpu.PTW0.ADDR, SDWeven, SDWodd, cpu.SDW0.ADDR,
462 cpu.SDW0.R1, cpu.SDW0.R2, cpu.SDW0.R3, cpu.SDW0.BOUND,
463 cpu.SDW0.R, cpu.SDW0.E, cpu.SDW0.W, cpu.SDW0.P, cpu.SDW0.U,
464 cpu.SDW0.G, cpu.SDW0.C, cpu.SDW0.DF, cpu.SDW0.FC, cpu.SDW0.FE,
465 cpu.SDW0.USE);
466 }
467
468
469
470
471
472 static void fetch_nsdw (word15 segno)
473 {
474 DBGAPP ("%s (0):segno=%05o\n", __func__, segno);
475
476 PNL (L68_ (cpu.apu.state |= apu_FSDN;))
477
478 set_apu_status (apuStatus_SDWNP);
479
480 if (2 * segno >= 16 * (cpu.DSBR.BND + 1))
481 {
482 DBGAPP ("%s (1):Access Violation, out of segment bounds for "
483 "segno=%05o DSBR.BND=%d\n",
484 __func__, segno, cpu.DSBR.BND);
485
486 PNL (cpu.acvFaults |= ACV15;)
487 PNL (L68_ (cpu.apu.state |= apu_FLT;))
488 doFault (FAULT_ACV, fst_acv15,
489 "acvFault fetch_dsptw: out of segment bounds fault");
490 }
491 DBGAPP ("%s (2):fetching SDW from %05o\n",
492 __func__, cpu.DSBR.ADDR + 2u * segno);
493
494 word36 SDWeven, SDWodd;
495 core_read2 ((cpu.DSBR.ADDR + 2u * segno) & PAMASK,
496 & SDWeven, & SDWodd, __func__);
497
498
499 cpu.SDW0.ADDR = (SDWeven >> 12) & 077777777;
500 cpu.SDW0.R1 = (SDWeven >> 9) & 7;
501 cpu.SDW0.R2 = (SDWeven >> 6) & 7;
502 cpu.SDW0.R3 = (SDWeven >> 3) & 7;
503 cpu.SDW0.DF = TSTBIT (SDWeven, 2);
504 cpu.SDW0.FC = SDWeven & 3;
505
506
507 cpu.SDW0.BOUND = (SDWodd >> 21) & 037777;
508 cpu.SDW0.R = TSTBIT (SDWodd, 20);
509 cpu.SDW0.E = TSTBIT (SDWodd, 19);
510 cpu.SDW0.W = TSTBIT (SDWodd, 18);
511 cpu.SDW0.P = TSTBIT (SDWodd, 17);
512 cpu.SDW0.U = TSTBIT (SDWodd, 16);
513 cpu.SDW0.G = TSTBIT (SDWodd, 15);
514 cpu.SDW0.C = TSTBIT (SDWodd, 14);
515 cpu.SDW0.EB = SDWodd & 037777;
516
517 L68_ (
518 if (cpu.MR_cache.emr && cpu.MR_cache.ihr)
519 add_l68_APU_history (0 );
520 )
521 #ifndef SPEED
522 char buf[256];
523 (void)buf;
524 DBGAPP ("%s (2):SDW0=%s\n", __func__, str_SDW0 (buf, & cpu.SDW0));
525 #endif
526 }
527
528 #ifdef TESTING
529 static char *str_sdw (char * buf, sdw_s *SDW)
530 {
531 if (! SDW->FE)
532 sprintf (buf, "*** SDW Uninitialized ***");
533 else
534 sprintf (buf,
535 "ADDR:%06o R1:%o R2:%o R3:%o BOUND:%o R:%o E:%o W:%o P:%o "
536 "U:%o G:%o C:%o CL:%o DF:%o FC:%o POINTER=%o USE=%d",
537 SDW->ADDR, SDW->R1, SDW->R2, SDW->R3, SDW->BOUND,
538 SDW->R, SDW->E, SDW->W, SDW->P, SDW->U,
539 SDW->G, SDW->C, SDW->EB, SDW->DF, SDW->FC,
540 SDW->POINTER, SDW->USE);
541 return buf;
542 }
543
544
545
546
547
548 # ifdef TESTING
549 t_stat dump_sdwam (void)
550 {
551 char buf[256];
552 (void)buf;
553 for (int _n = 0; _n < N_MODEL_WAM_ENTRIES; _n++)
554 {
555 sdw_s *p = & cpu.SDWAM[_n];
556
557 if (p->FE)
558 sim_printf ("SDWAM n:%d %s\n", _n, str_sdw (buf, p));
559 }
560 return SCPE_OK;
561 }
562 # endif
563 #endif
564
565 static uint to_be_discarded_am (word6 LRU)
566 {
567
568
569
570
571
572
573
574
575
576
577
578
579 if ((LRU & 070) == 070) return 0;
580 if ((LRU & 046) == 006) return 1;
581 if ((LRU & 025) == 001) return 2;
582 return 3;
583 }
584
585
586
587
588
589 static void load_sdwam (word15 segno, bool nomatch)
590 {
591 cpu.SDW0.POINTER = segno;
592 cpu.SDW0.USE = 0;
593
594 cpu.SDW0.FE = true;
595
596 cpu.SDW = & cpu.SDW0;
597
598 if (nomatch || (! cpu.tweaks.enable_wam) || (! cpu.cu.SD_ON))
599 {
600 DBGAPP ("%s: SDWAM disabled\n", __func__);
601 return;
602 }
603
604 if (cpu.tweaks.l68_mode) {
605
606
607
608
609
610
611
612 for (int _n = 0; _n < N_L68_WAM_ENTRIES; _n++) {
613 sdw_s * p = & cpu.SDWAM[_n];
614 if (! p->FE || p->USE == 0) {
615 DBGAPP ("%s(1):SDWAM[%d] FE=0 || USE=0\n", __func__, _n);
616
617 * p = cpu.SDW0;
618 p->POINTER = segno;
619 p->USE = 0;
620 p->FE = true;
621
622 for (int _h = 0; _h < N_L68_WAM_ENTRIES; _h++) {
623 sdw_s * q = & cpu.SDWAM[_h];
624 q->USE -= 1;
625 q->USE &= N_L68_WAM_MASK;
626 }
627
628 cpu.SDW = p;
629
630 char buf[256];
631 (void) buf;
632 #ifdef TESTING
633 DBGAPP ("%s(2):SDWAM[%d]=%s\n", __func__, _n, str_sdw (buf, p));
634 #endif
635 return;
636 }
637 }
638
639 #ifdef TESTING
640 DBGAPP ("%s(3) no USE=0 found for segment=%d\n", __func__, segno);
641 sim_printf ("%s(%05o): no USE=0 found!\n", __func__, segno);
642 dump_sdwam ();
643 #endif
644 }
645
646 if (! cpu.tweaks.l68_mode) {
647 uint setno = segno & 017;
648 uint toffset;
649 sdw_s *p;
650 for (toffset = 0; toffset < 64; toffset += 16) {
651 p = & cpu.SDWAM[toffset + setno];
652 if (!p->FE)
653 break;
654 }
655 if (toffset == 64) {
656 toffset = to_be_discarded_am (p->USE) << 4;
657 p = & cpu.SDWAM[toffset + setno];
658 }
659 DBGAPP ("%s(1):SDWAM[%d] FE=0 || LRU\n", __func__, toffset + setno);
660
661 word6 u = calc_hit_am (p->USE, toffset >> 4);
662 * p = cpu.SDW0;
663 p->POINTER = segno;
664 p->FE = true;
665 cpu.SDW = p;
666
667 for (uint toffset1 = 0; toffset1 < 64; toffset1 += 16) {
668 p = & cpu.SDWAM[toffset1 + setno];
669 if (p->FE)
670 p->USE = u;
671 }
672
673 char buf[256];
674 (void) buf;
675 #ifdef TESTING
676 DBGAPP ("%s(2):SDWAM[%d]=%s\n", __func__, toffset + setno, str_sdw (buf, cpu.SDW));
677 #endif
678 }
679 }
680
681 static ptw_s * fetch_ptw_from_ptwam (word15 segno, word18 CA)
682 {
683 if ((! cpu.tweaks.enable_wam) || (! cpu.cu.PT_ON))
684 {
685 DBGAPP ("%s: PTWAM disabled\n", __func__);
686 return NULL;
687 }
688
689 if (cpu.tweaks.l68_mode) {
690 int nwam = N_L68_WAM_ENTRIES;
691 for (int _n = 0; _n < nwam; _n++)
692 {
693 if (cpu.PTWAM[_n].FE && ((CA >> 6) & 07760) == cpu.PTWAM[_n].PAGENO &&
694 cpu.PTWAM[_n].POINTER == segno)
695 {
696 DBGAPP ("%s: found match for segno=%o pageno=%o "
697 "at _n=%d\n",
698 __func__, segno, cpu.PTWAM[_n].PAGENO, _n);
699 cpu.cu.PTWAMM = 1;
700 cpu.PTWAMR = (word4) _n;
701 cpu.PTW = & cpu.PTWAM[_n];
702
703
704
705
706
707
708
709 for (int _h = 0; _h < nwam; _h++)
710 {
711 if (cpu.PTWAM[_h].USE > cpu.PTW->USE)
712 cpu.PTWAM[_h].USE -= 1;
713 }
714 cpu.PTW->USE = N_L68_WAM_ENTRIES - 1;
715 #ifdef do_selftestPTWAM
716 selftest_ptwaw ();
717 #endif
718 DBGAPP ("%s: ADDR 0%o U %o M %o F %o FC %o\n",
719 __func__, cpu.PTW->ADDR, cpu.PTW->U, cpu.PTW->M,
720 cpu.PTW->DF, cpu.PTW->FC);
721 return cpu.PTW;
722 }
723 }
724 }
725
726 DPS8M_ (
727 uint setno = (CA >> 10) & 017;
728 uint toffset;
729 ptw_s *p;
730 for (toffset = 0; toffset < 64; toffset += 16)
731 {
732 p = & cpu.PTWAM[toffset + setno];
733
734 if (p->FE && ((CA >> 6) & 07760) == p->PAGENO && p->POINTER == segno)
735 {
736 DBGAPP ("%s: found match for segno=%o pageno=%o "
737 "at _n=%d\n",
738 __func__, segno, p->PAGENO, toffset + setno);
739 cpu.cu.PTWAMM = 1;
740 cpu.PTWAMR = (word6) (toffset + setno);
741 cpu.PTW = p;
742
743 word6 u = calc_hit_am (p->USE, toffset >> 4);
744 for (toffset = 0; toffset < 64; toffset += 16)
745 {
746 p = & cpu.PTWAM[toffset + setno];
747 if (p->FE)
748 p->USE = u;
749 }
750
751 DBGAPP ("%s: ADDR 0%o U %o M %o F %o FC %o\n",
752 __func__, cpu.PTW->ADDR, cpu.PTW->U, cpu.PTW->M,
753 cpu.PTW->DF, cpu.PTW->FC);
754 return cpu.PTW;
755 }
756 }
757 )
758 cpu.cu.PTWAMM = 0;
759 return NULL;
760 }
761
762 static void fetch_ptw (sdw_s *sdw, word18 offset)
763 {
764
765
766
767 PNL (L68_ (cpu.apu.state |= apu_FPTW;))
768 set_apu_status (apuStatus_PTW);
769
770
771 word24 x2 = (offset) / 1024;
772
773 word36 PTWx2;
774
775 DBGAPP ("%s address %08o\n", __func__, sdw->ADDR + x2);
776
777 PNL (cpu.lastPTWOffset = offset;)
778 PNL (cpu.lastPTWIsDS = false;)
779
780 #ifdef THREADZ
781 bool lck = get_rmw_lock ();
782 if (! lck)
783 lock_rmw ();
784 #endif
785 #ifdef LOCKLESS
786 core_read_lock ((sdw->ADDR + x2) & PAMASK, & PTWx2, __func__);
787 #else
788 core_read ((sdw->ADDR + x2) & PAMASK, & PTWx2, __func__);
789 #endif
790
791 cpu.PTW0.ADDR = GETHI (PTWx2);
792 cpu.PTW0.U = TSTBIT (PTWx2, 9);
793 cpu.PTW0.M = TSTBIT (PTWx2, 6);
794 cpu.PTW0.DF = TSTBIT (PTWx2, 2);
795 cpu.PTW0.FC = PTWx2 & 3;
796
797
798 #ifndef LOCKLESS
799 if (! cpu.PTW0.U)
800 #endif
801 {
802 PTWx2 = SETBIT (PTWx2, 9);
803 #ifdef LOCKLESS
804 core_write_unlock ((sdw->ADDR + x2) & PAMASK, PTWx2, __func__);
805 #else
806 core_write ((sdw->ADDR + x2) & PAMASK, PTWx2, __func__);
807 #endif
808 cpu.PTW0.U = 1;
809 }
810
811 #ifdef THREADZ
812 if (! lck)
813 unlock_rmw ();
814 #endif
815
816 L68_ (if (cpu.MR_cache.emr && cpu.MR_cache.ihr)
817 add_l68_APU_history (APUH_FPTW);)
818
819 DBGAPP ("%s x2 0%o sdw->ADDR 0%o PTWx2 0%012"PRIo64" "
820 "PTW0: ADDR 0%o U %o M %o F %o FC %o\n",
821 __func__, x2, sdw->ADDR, PTWx2, cpu.PTW0.ADDR, cpu.PTW0.U,
822 cpu.PTW0.M, cpu.PTW0.DF, cpu.PTW0.FC);
823 }
824
825 static void loadPTWAM (word15 segno, word18 offset, UNUSED bool nomatch)
826 {
827 cpu.PTW0.PAGENO = (offset >> 6) & 07760;
828 cpu.PTW0.POINTER = segno;
829 cpu.PTW0.USE = 0;
830 cpu.PTW0.FE = true;
831
832 cpu.PTW = & cpu.PTW0;
833 if (nomatch || (! cpu.tweaks.enable_wam) || (! cpu.cu.PT_ON))
834 {
835 DBGAPP ("loadPTWAM: PTWAM disabled\n");
836 return;
837 }
838
839 if (cpu.tweaks.l68_mode) {
840
841
842
843
844
845
846 for (int _n = 0; _n < N_L68_WAM_ENTRIES; _n++)
847 {
848 ptw_s * p = & cpu.PTWAM[_n];
849 if (! p->FE || p->USE == 0)
850 {
851 DBGAPP ("loadPTWAM(1):PTWAM[%d] FE=0 || USE=0\n", _n);
852 *p = cpu.PTW0;
853 p->PAGENO = (offset >> 6) & 07760;
854 p->POINTER = segno;
855 p->USE = 0;
856 p->FE = true;
857
858 for (int _h = 0; _h < N_L68_WAM_ENTRIES; _h++)
859 {
860 ptw_s * q = & cpu.PTWAM[_h];
861 q->USE -= 1;
862 q->USE &= N_L68_WAM_MASK;
863 }
864
865 cpu.PTW = p;
866 DBGAPP ("loadPTWAM(2): ADDR 0%o U %o M %o F %o FC %o "
867 "POINTER=%o PAGENO=%o USE=%d\n",
868 cpu.PTW->ADDR, cpu.PTW->U, cpu.PTW->M, cpu.PTW->DF,
869 cpu.PTW->FC, cpu.PTW->POINTER, cpu.PTW->PAGENO,
870 cpu.PTW->USE);
871 #ifdef do_selftestPTWAM
872 selftest_ptwaw ();
873 #endif
874 return;
875 }
876 }
877
878 sim_printf ("loadPTWAM(segno=%05o, offset=%012o): no USE=0 found!\n",
879 segno, offset);
880 }
881
882 DPS8M_ (
883 uint setno = (offset >> 10) & 017;
884 uint toffset;
885 ptw_s *p;
886 for (toffset = 0; toffset < 64; toffset += 16)
887 {
888 p = & cpu.PTWAM[toffset + setno];
889 if (! p->FE)
890 break;
891 }
892 if (toffset == 64)
893 {
894 toffset = to_be_discarded_am (p->USE) << 4;
895 p = & cpu.PTWAM[toffset + setno];
896 }
897
898 DBGAPP ("loadPTWAM(1):PTWAM[%d] FE=0 || LRU\n",
899 toffset + setno);
900
901 word6 u = calc_hit_am (p->USE, toffset >> 4);
902 * p = cpu.PTW0;
903 p->PAGENO = (offset >> 6) & 07760;
904 p->POINTER = segno;
905 p->FE = true;
906 cpu.PTW = p;
907
908 for (uint toffset1 = 0; toffset1 < 64; toffset1 += 16)
909 {
910 p = & cpu.PTWAM[toffset1 + setno];
911 if (p->FE)
912 p->USE = u;
913 }
914
915 DBGAPP ("loadPTWAM(2): ADDR 0%o U %o M %o F %o FC %o POINTER=%o "
916 "PAGENO=%o USE=%d\n",
917 cpu.PTW->ADDR, cpu.PTW->U, cpu.PTW->M, cpu.PTW->DF,
918 cpu.PTW->FC, cpu.PTW->POINTER, cpu.PTW->PAGENO, cpu.PTW->USE);
919 )
920 }
921
922
923
924
925
926 static void modify_ptw (sdw_s *sdw, word18 offset)
927 {
928 PNL (L68_ (cpu.apu.state |= apu_MPTW;))
929
930 word24 x2 = offset / 1024;
931
932 word36 PTWx2;
933
934 set_apu_status (apuStatus_MPTW);
935
936 #ifdef THREADZ
937 bool lck = get_rmw_lock ();
938 if (! lck)
939 lock_rmw ();
940 #endif
941 #ifdef LOCKLESS
942 core_read_lock ((sdw->ADDR + x2) & PAMASK, & PTWx2, __func__);
943 PTWx2 = SETBIT (PTWx2, 6);
944 core_write_unlock ((sdw->ADDR + x2) & PAMASK, PTWx2, __func__);
945 #else
946 core_read ((sdw->ADDR + x2) & PAMASK, & PTWx2, __func__);
947 PTWx2 = SETBIT (PTWx2, 6);
948 core_write ((sdw->ADDR + x2) & PAMASK, PTWx2, __func__);
949 #endif
950 #ifdef THREADZ
951 if (! lck)
952 unlock_rmw ();
953 #endif
954 cpu.PTW->M = 1;
955 L68_ (if (cpu.MR_cache.emr && cpu.MR_cache.ihr)
956 add_l68_APU_history (APUH_MPTW);)
957 }
958
959 static void do_ptw2 (sdw_s *sdw, word18 offset)
960 {
961 PNL (L68_ (cpu.apu.state |= apu_FPTW2;))
962 set_apu_status (apuStatus_PTW2);
963
964
965 word24 x2 = (offset) / 1024;
966
967 word36 PTWx2n;
968
969 DBGAPP ("%s address %08o\n", __func__, sdw->ADDR + x2 + 1);
970
971 core_read ((sdw->ADDR + x2 + 1) & PAMASK, & PTWx2n, __func__);
972
973 ptw_s PTW2;
974 PTW2.ADDR = GETHI (PTWx2n);
975 PTW2.U = TSTBIT (PTWx2n, 9);
976 PTW2.M = TSTBIT (PTWx2n, 6);
977 PTW2.DF = TSTBIT (PTWx2n, 2);
978 PTW2.FC = PTWx2n & 3;
979
980 L68_ (if (cpu.MR_cache.emr && cpu.MR_cache.ihr)
981 add_l68_APU_history (APUH_FPTW2);)
982
983 DBGAPP ("%s x2 0%o sdw->ADDR 0%o PTW2 0%012"PRIo64" "
984 "PTW2: ADDR 0%o U %o M %o F %o FC %o\n",
985 __func__, x2, sdw->ADDR, PTWx2n, PTW2.ADDR, PTW2.U, PTW2.M,
986 PTW2.DF, PTW2.FC);
987
988
989
990 if ((PTW2.ADDR & 0777760) == (cpu.PTW->ADDR & 0777760) + 16)
991
992 if (! PTW2.DF)
993
994 doFault (FAULT_DF0 + PTW2.FC, fst_zero, "PTW2.F == 0");
995 }
996
997
998
999
1000
1001 #ifndef QUIET_UNUSED
1002 static char *str_access_type (MemoryAccessType accessType)
1003 {
1004 switch (accessType)
1005 {
1006 case UnknownMAT: return "Unknown";
1007 case OperandRead: return "OperandRead";
1008 case OperandWrite: return "OperandWrite";
1009 default: return "???";
1010 }
1011 }
1012 #endif
1013
1014 #ifndef QUIET_UNUSED
1015 static char *str_acv (_fault_subtype acv)
1016 {
1017 switch (acv)
1018 {
1019 case ACV0: return "Illegal ring order (ACV0=IRO)";
1020 case ACV1: return "Not in execute bracket (ACV1=OEB)";
1021 case ACV2: return "No execute permission (ACV2=E-OFF)";
1022 case ACV3: return "Not in read bracket (ACV3=ORB)";
1023 case ACV4: return "No read permission (ACV4=R-OFF)";
1024 case ACV5: return "Not in write bracket (ACV5=OWB)";
1025 case ACV6: return "No write permission (ACV6=W-OFF)";
1026 case ACV7: return "Call limiter fault (ACV7=NO GA)";
1027 case ACV8: return "Out of call brackets (ACV8=OCB)";
1028 case ACV9: return "Outward call (ACV9=OCALL)";
1029 case ACV10: return "Bad outward call (ACV10=BOC)";
1030 case ACV11: return "Inward return (ACV11=INRET) XXX ??";
1031 case ACV12: return "Invalid ring crossing (ACV12=CRT)";
1032 case ACV13: return "Ring alarm (ACV13=RALR)";
1033 case ACV14: return "Associative memory error XXX ??";
1034 case ACV15: return "Out of segment bounds (ACV15=OOSB)";
1035
1036
1037
1038
1039 default:
1040 break;
1041 }
1042 return "unhandled acv in str_acv";
1043 }
1044 #endif
1045
1046 #if defined (TESTING) || defined (OLDAPP)
1047 static char *str_pct (processor_cycle_type t)
1048 {
1049 switch (t)
1050 {
1051 case UNKNOWN_CYCLE: return "UNKNOWN_CYCLE";
1052 case OPERAND_STORE: return "OPERAND_STORE";
1053 case OPERAND_READ: return "OPERAND_READ";
1054 case INDIRECT_WORD_FETCH: return "INDIRECT_WORD_FETCH";
1055 # ifdef LOCKLESS
1056 case OPERAND_RMW: return "OPERAND_RMW";
1057 case APU_DATA_RMW: return "APU_DATA_RMW";
1058 # endif
1059 default:
1060 return "Unhandled processor_cycle_type";
1061 }
1062 }
1063 #endif
1064
1065 #ifndef OLDAPP
1066 word24 do_append_cycle (processor_cycle_type thisCycle, word36 * data, uint nWords) {
1067 switch (thisCycle) {
1068 case OPERAND_STORE:
1069 return doAppendCycleOperandStore (data, nWords);
1070 case OPERAND_READ:
1071 return doAppendCycleOperandRead (data, nWords);
1072 case INDIRECT_WORD_FETCH:
1073 return doAppendCycleIndirectWordFetch (data, nWords);
1074 case RTCD_OPERAND_FETCH:
1075 return doAppendCycleRTCDOperandFetch (data, nWords);
1076 case INSTRUCTION_FETCH:
1077 return doAppendCycleInstructionFetch (data, nWords);
1078 case APU_DATA_READ:
1079 return doAppendCycleAPUDataRead (data, nWords);
1080 case APU_DATA_STORE:
1081 return doAppendCycleAPUDataStore (data, nWords);
1082 case ABSA_CYCLE:
1083 return doAppendCycleABSA (data, nWords);
1084 # ifdef LOCKLESS
1085 case OPERAND_RMW:
1086 return doAppendCycleOperandRMW (data, nWords);
1087 case APU_DATA_RMW:
1088 return doAppendCycleAPUDataRMW (data, nWords);
1089 # endif
1090 case UNKNOWN_CYCLE:
1091 default:
1092 fprintf (stderr, "\rFATAL: APU unknown cycle %llu! Aborting at %s[%s:%d]\r\n",
1093 (long long unsigned)thisCycle, __func__, __FILE__, __LINE__);
1094 # if defined(USE_BACKTRACE)
1095 # ifdef SIGUSR2
1096 (void)raise(SIGUSR2);
1097
1098 # endif
1099 # endif
1100 abort();
1101 }
1102 }
1103 #endif
1104
1105 #ifndef OLDAPP
1106 # include "doAppendCycleOperandStore.h"
1107 # include "doAppendCycleOperandRead.h"
1108 # include "doAppendCycleIndirectWordFetch.h"
1109 # include "doAppendCycleRTCDOperandFetch.h"
1110 # include "doAppendCycleInstructionFetch.h"
1111 # include "doAppendCycleAPUDataRead.h"
1112 # include "doAppendCycleAPUDataStore.h"
1113 # include "doAppendCycleABSA.h"
1114 # ifdef LOCKLESS
1115 # include "doAppendCycleOperandRMW.h"
1116 # include "doAppendCycleAPUDataRMW.h"
1117 # endif
1118 #endif
1119
1120 #ifdef OLDAPP
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196 word24 do_append_cycle (processor_cycle_type thisCycle, word36 * data,
1197 uint nWords)
1198 {
1199 DCDstruct * i = & cpu.currentInstruction;
1200 DBGAPP ("do_append_cycle(Entry) thisCycle=%s\n",
1201 str_pct (thisCycle));
1202 DBGAPP ("do_append_cycle(Entry) lastCycle=%s\n",
1203 str_pct (cpu.apu.lastCycle));
1204 DBGAPP ("do_append_cycle(Entry) CA %06o\n",
1205 cpu.TPR.CA);
1206 DBGAPP ("do_append_cycle(Entry) n=%2u\n",
1207 nWords);
1208 DBGAPP ("do_append_cycle(Entry) PPR.PRR=%o PPR.PSR=%05o\n",
1209 cpu.PPR.PRR, cpu.PPR.PSR);
1210 DBGAPP ("do_append_cycle(Entry) TPR.TRR=%o TPR.TSR=%05o\n",
1211 cpu.TPR.TRR, cpu.TPR.TSR);
1212
1213 if (i->b29)
1214 {
1215 DBGAPP ("do_append_cycle(Entry) isb29 PRNO %o\n",
1216 GET_PRN (IWB_IRODD));
1217 }
1218
1219 bool StrOp = (thisCycle == OPERAND_STORE ||
1220 thisCycle == APU_DATA_STORE);
1221
1222 bool nomatch = true;
1223 if (cpu.tweaks.enable_wam)
1224 {
1225
1226
1227
1228
1229
1230 nomatch = ((i->opcode == 0232 || i->opcode == 0254 ||
1231 i->opcode == 0154 || i->opcode == 0173) && i->opcodeX) ||
1232 ((i->opcode == 0557 || i->opcode == 0257) && ! i->opcodeX);
1233 }
1234
1235 processor_cycle_type lastCycle = cpu.apu.lastCycle;
1236 cpu.apu.lastCycle = thisCycle;
1237
1238 DBGAPP ("do_append_cycle(Entry) XSF %o\n", cpu.cu.XSF);
1239
1240 PNL (L68_ (cpu.apu.state = 0;))
1241
1242 cpu.RSDWH_R1 = 0;
1243
1244 cpu.acvFaults = 0;
1245
1246
1247 # define FMSG(x)
1248 FMSG (char * acvFaultsMsg = "<unknown>";)
1249
1250 word24 finalAddress = (word24) -1;
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260 word3 n = 0;
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275 if (thisCycle == RTCD_OPERAND_FETCH &&
1276 get_addr_mode() == ABSOLUTE_mode &&
1277 ! (cpu.cu.XSF || cpu.currentInstruction.b29) )
1278 {
1279 cpu.TPR.TSR = 0;
1280 DBGAPP ("RTCD_OPERAND_FETCH ABSOLUTE mode set TSR %05o TRR %o\n",
1281 cpu.TPR.TSR, cpu.TPR.TRR);
1282 }
1283
1284 goto A;
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296 A:;
1297
1298
1299 PNL (cpu.APUMemAddr = cpu.TPR.CA;)
1300
1301 DBGAPP ("do_append_cycle(A)\n");
1302
1303
1304 if (nomatch || ! fetch_sdw_from_sdwam (cpu.TPR.TSR))
1305 {
1306
1307 DBGAPP ("do_append_cycle(A):SDW for segment %05o not in SDWAM\n",
1308 cpu.TPR.TSR);
1309
1310 DBGAPP ("do_append_cycle(A):DSBR.U=%o\n",
1311 cpu.DSBR.U);
1312
1313 if (cpu.DSBR.U == 0)
1314 {
1315 fetch_dsptw (cpu.TPR.TSR);
1316
1317 if (! cpu.PTW0.DF)
1318 doFault (FAULT_DF0 + cpu.PTW0.FC, fst_zero,
1319 "do_append_cycle(A): PTW0.F == 0");
1320
1321 if (! cpu.PTW0.U)
1322 modify_dsptw (cpu.TPR.TSR);
1323
1324 fetch_psdw (cpu.TPR.TSR);
1325 }
1326 else
1327 fetch_nsdw (cpu.TPR.TSR);
1328
1329 if (cpu.SDW0.DF == 0)
1330 {
1331 if (thisCycle != ABSA_CYCLE)
1332 {
1333 DBGAPP ("do_append_cycle(A): SDW0.F == 0! "
1334 "Initiating directed fault\n");
1335
1336 doFault (FAULT_DF0 + cpu.SDW0.FC, fst_zero, "SDW0.F == 0");
1337 }
1338 }
1339
1340 load_sdwam (cpu.TPR.TSR, nomatch);
1341 }
1342 DBGAPP ("do_append_cycle(A) R1 %o R2 %o R3 %o E %o\n",
1343 cpu.SDW->R1, cpu.SDW->R2, cpu.SDW->R3, cpu.SDW->E);
1344
1345
1346 cpu.RSDWH_R1 = cpu.SDW->R1;
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358 DBGAPP ("do_append_cycle(B)\n");
1359
1360
1361
1362
1363 if (! (cpu.SDW->R1 <= cpu.SDW->R2 && cpu.SDW->R2 <= cpu.SDW->R3))
1364 {
1365
1366 cpu.acvFaults |= ACV0;
1367 PNL (L68_ (cpu.apu.state |= apu_FLT;))
1368 FMSG (acvFaultsMsg = "acvFaults(B) C(SDW.R1) <= C(SDW.R2) <= "
1369 "C(SDW .R3)";)
1370 }
1371
1372
1373
1374
1375
1376
1377
1378 if (thisCycle == INSTRUCTION_FETCH &&
1379 i->opcode == 0610 && ! i->opcodeX)
1380 goto C;
1381 else if (lastCycle == RTCD_OPERAND_FETCH)
1382 sim_warn ("%s: lastCycle == RTCD_OPERAND_FETCH opcode %0#o\n", __func__, i->opcode);
1383
1384
1385
1386
1387
1388
1389
1390 if (thisCycle == OPERAND_READ && (i->info->flags & CALL6_INS))
1391 goto E;
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415 if (thisCycle == INSTRUCTION_FETCH ||
1416 (thisCycle == OPERAND_READ && (i->info->flags & TRANSFER_INS)))
1417 goto F;
1418
1419
1420
1421
1422
1423 # ifdef LOCKLESS
1424 if (!StrOp || thisCycle == OPERAND_RMW || thisCycle == APU_DATA_RMW)
1425 # else
1426 if (!StrOp)
1427 # endif
1428 {
1429 DBGAPP ("do_append_cycle(B):!STR-OP\n");
1430
1431
1432
1433 if (cpu.TPR.TRR > cpu.SDW->R2)
1434 {
1435 DBGAPP ("ACV3\n");
1436 DBGAPP ("do_append_cycle(B) ACV3\n");
1437
1438 cpu.acvFaults |= ACV3;
1439 PNL (L68_ (cpu.apu.state |= apu_FLT;))
1440 FMSG (acvFaultsMsg = "acvFaults(B) C(TPR.TRR) > C(SDW .R2)";)
1441 }
1442
1443 if (cpu.SDW->R == 0)
1444 {
1445
1446 cpu.TPR.TRR = cpu.PPR.PRR;
1447
1448
1449 if (cpu.PPR.PSR != cpu.TPR.TSR)
1450 {
1451 DBGAPP ("ACV4\n");
1452 DBGAPP ("do_append_cycle(B) ACV4\n");
1453
1454 cpu.acvFaults |= ACV4;
1455 PNL (L68_ (cpu.apu.state |= apu_FLT;))
1456 FMSG (acvFaultsMsg = "acvFaults(B) C(PPR.PSR) = C(TPR.TSR)";)
1457 }
1458
1459
1460
1461
1462
1463
1464 }
1465 }
1466
1467
1468
1469
1470 # ifdef LOCKLESS
1471 if (StrOp || thisCycle == OPERAND_RMW || thisCycle == APU_DATA_RMW)
1472 # else
1473 if (StrOp)
1474 # endif
1475 {
1476 DBGAPP ("do_append_cycle(B):STR-OP\n");
1477
1478
1479 if (cpu.TPR.TSR == cpu.PPR.PSR)
1480 cpu.TPR.TRR = cpu.PPR.PRR;
1481
1482
1483 if (cpu.TPR.TRR > cpu.SDW->R1)
1484 {
1485 DBGAPP ("ACV5 TRR %o R1 %o\n",
1486 cpu.TPR.TRR, cpu.SDW->R1);
1487
1488 cpu.acvFaults |= ACV5;
1489 PNL (L68_ (cpu.apu.state |= apu_FLT;))
1490 FMSG (acvFaultsMsg = "acvFaults(B) C(TPR.TRR) > C(SDW .R1)";)
1491 }
1492
1493 if (! cpu.SDW->W)
1494 {
1495
1496 cpu.TPR.TRR = cpu.PPR.PRR;
1497
1498 DBGAPP ("ACV6\n");
1499
1500 cpu.acvFaults |= ACV6;
1501 PNL (L68_ (cpu.apu.state |= apu_FLT;))
1502 FMSG (acvFaultsMsg = "acvFaults(B) ACV6 = W-OFF";)
1503 }
1504
1505 }
1506 goto G;
1507
1508
1509
1510
1511
1512
1513
1514 C:;
1515 DBGAPP ("do_append_cycle(C)\n");
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525 if (cpu.TPR.TRR < cpu.SDW->R1 ||
1526 cpu.TPR.TRR > cpu.SDW->R2)
1527 {
1528 DBGAPP ("ACV1 c\n");
1529 DBGAPP ("acvFaults(C) ACV1 ! ( C(SDW .R1) %o <= C(TPR.TRR) %o <= C(SDW .R2) %o )\n",
1530 cpu.SDW->R1, cpu.TPR.TRR, cpu.SDW->R2);
1531
1532 cpu.acvFaults |= ACV1;
1533 PNL (L68_ (cpu.apu.state |= apu_FLT;))
1534 FMSG (acvFaultsMsg = "acvFaults(C) C(SDW.R1 > C(TPR.TRR) > C(SDW.R2)";)
1535 }
1536
1537 if (! cpu.SDW->E)
1538 {
1539 DBGAPP ("ACV2 a\n");
1540 DBGAPP ("do_append_cycle(C) ACV2\n");
1541
1542 cpu.acvFaults |= ACV2;
1543 PNL (L68_ (cpu.apu.state |= apu_FLT;))
1544 FMSG (acvFaultsMsg = "acvFaults(C) SDW.E";)
1545 }
1546 if (cpu.TPR.TRR > cpu.PPR.PRR)
1547 sim_warn ("rtcd: outbound call cpu.TPR.TRR %d cpu.PPR.PRR %d\n",
1548 cpu.TPR.TRR, cpu.PPR.PRR);
1549
1550 if (cpu.TPR.TRR < cpu.PPR.PRR)
1551 {
1552 DBGAPP ("ACV11\n");
1553 DBGAPP ("do_append_cycle(C) ACV11\n");
1554
1555 cpu.acvFaults |= ACV11;
1556 PNL (L68_ (cpu.apu.state |= apu_FLT;))
1557 FMSG (acvFaultsMsg = "acvFaults(C) TRR>=PRR";)
1558 }
1559
1560 D:;
1561 DBGAPP ("do_append_cycle(D)\n");
1562
1563
1564
1565
1566
1567 if (cpu.rRALR == 0)
1568 goto G;
1569
1570
1571 if (! (cpu.PPR.PRR < cpu.rRALR))
1572 {
1573 DBGAPP ("ACV13\n");
1574 DBGAPP ("acvFaults(D) C(PPR.PRR) %o < RALR %o\n",
1575 cpu.PPR.PRR, cpu.rRALR);
1576 cpu.acvFaults |= ACV13;
1577 PNL (L68_ (cpu.apu.state |= apu_FLT;))
1578 FMSG (acvFaultsMsg = "acvFaults(D) C(PPR.PRR) < RALR";)
1579 }
1580
1581 goto G;
1582
1583
1584
1585
1586
1587
1588
1589 E:;
1590
1591
1592
1593
1594
1595
1596 DBGAPP ("do_append_cycle(E): CALL6\n");
1597 DBGAPP ("do_append_cycle(E): E %o G %o PSR %05o TSR %05o CA %06o "
1598 "EB %06o R %o%o%o TRR %o PRR %o\n",
1599 cpu.SDW->E, cpu.SDW->G, cpu.PPR.PSR, cpu.TPR.TSR, cpu.TPR.CA,
1600 cpu.SDW->EB, cpu.SDW->R1, cpu.SDW->R2, cpu.SDW->R3,
1601 cpu.TPR.TRR, cpu.PPR.PRR);
1602
1603
1604 if (! cpu.SDW->E)
1605 {
1606 DBGAPP ("ACV2 b\n");
1607 DBGAPP ("do_append_cycle(E) ACV2\n");
1608
1609 cpu.acvFaults |= ACV2;
1610 PNL (L68_ (cpu.apu.state |= apu_FLT;))
1611 FMSG (acvFaultsMsg = "acvFaults(E) SDW .E set OFF";)
1612 }
1613
1614
1615 if (cpu.SDW->G)
1616 goto E1;
1617
1618
1619 if (cpu.PPR.PSR == cpu.TPR.TSR && ! TST_I_ABS)
1620 goto E1;
1621
1622
1623
1624
1625 if (cpu.TPR.CA >= (word18) cpu.SDW->EB)
1626 {
1627 DBGAPP ("ACV7\n");
1628 DBGAPP ("do_append_cycle(E) ACV7\n");
1629
1630 cpu.acvFaults |= ACV7;
1631 PNL (L68_ (cpu.apu.state |= apu_FLT;))
1632 FMSG (acvFaultsMsg = "acvFaults(E) TPR.CA4-17 >= SDW.CL";)
1633 }
1634
1635 E1:
1636 DBGAPP ("do_append_cycle(E1): CALL6 (cont'd)\n");
1637
1638
1639 if (cpu.TPR.TRR > cpu.SDW->R3)
1640 {
1641 DBGAPP ("ACV8\n");
1642 DBGAPP ("do_append_cycle(E) ACV8\n");
1643
1644 cpu.acvFaults |= ACV8;
1645 PNL (L68_ (cpu.apu.state |= apu_FLT;))
1646 FMSG (acvFaultsMsg = "acvFaults(E1) C(TPR.TRR) > SDW.R3";)
1647 }
1648
1649
1650 if (cpu.TPR.TRR < cpu.SDW->R1)
1651 {
1652 DBGAPP ("ACV9\n");
1653 DBGAPP ("do_append_cycle(E) ACV9\n");
1654
1655 cpu.acvFaults |= ACV9;
1656 PNL (L68_ (cpu.apu.state |= apu_FLT;))
1657 FMSG (acvFaultsMsg = "acvFaults(E1) C(TPR.TRR) < SDW.R1";)
1658 }
1659
1660
1661 if (cpu.TPR.TRR > cpu.PPR.PRR)
1662 {
1663
1664 if (cpu.PPR.PRR < cpu.SDW->R2)
1665 {
1666 DBGAPP ("ACV10\n");
1667 DBGAPP ("do_append_cycle(E) ACV10\n");
1668
1669 cpu.acvFaults |= ACV10;
1670 PNL (L68_ (cpu.apu.state |= apu_FLT;))
1671 FMSG (acvFaultsMsg = "acvFaults(E1) C(TPR.TRR) > C(PPR.PRR) && "
1672 "C(PPR.PRR) < SDW.R2";)
1673 }
1674 }
1675
1676 DBGAPP ("do_append_cycle(E1): CALL6 TPR.TRR %o SDW->R2 %o\n",
1677 cpu.TPR.TRR, cpu.SDW->R2);
1678
1679
1680 if (cpu.TPR.TRR > cpu.SDW->R2)
1681 {
1682
1683 cpu.TPR.TRR = cpu.SDW->R2;
1684 }
1685
1686 DBGAPP ("do_append_cycle(E1): CALL6 TPR.TRR %o\n", cpu.TPR.TRR);
1687
1688 goto G;
1689
1690
1691
1692
1693
1694
1695
1696 F:;
1697 PNL (L68_ (cpu.apu.state |= apu_PIAU;))
1698 DBGAPP ("do_append_cycle(F): transfer or instruction fetch\n");
1699
1700
1701
1702
1703
1704
1705
1706 if (cpu.TPR.TRR < cpu.SDW->R1 ||
1707 cpu.TPR.TRR > cpu.SDW->R2)
1708 {
1709 DBGAPP ("ACV1 a/b\n");
1710 DBGAPP ("acvFaults(F) ACV1 !( C(SDW .R1) %o <= C(TPR.TRR) %o <= C(SDW .R2) %o )\n",
1711 cpu.SDW->R1, cpu.TPR.TRR, cpu.SDW->R2);
1712 cpu.acvFaults |= ACV1;
1713 PNL (L68_ (cpu.apu.state |= apu_FLT;))
1714 FMSG (acvFaultsMsg = "acvFaults(F) C(TPR.TRR) < C(SDW .R1)";)
1715 }
1716
1717 if (! cpu.SDW->E)
1718 {
1719 DBGAPP ("ACV2 c \n");
1720 DBGAPP ("do_append_cycle(F) ACV2\n");
1721 cpu.acvFaults |= ACV2;
1722 PNL (L68_ (cpu.apu.state |= apu_FLT;))
1723 FMSG (acvFaultsMsg = "acvFaults(F) SDW .E set OFF";)
1724 }
1725
1726
1727 if (cpu.PPR.PRR != cpu.TPR.TRR)
1728 {
1729 DBGAPP ("ACV12\n");
1730 DBGAPP ("do_append_cycle(F) ACV12\n");
1731
1732 cpu.acvFaults |= ACV12;
1733 PNL (L68_ (cpu.apu.state |= apu_FLT;))
1734 FMSG (acvFaultsMsg = "acvFaults(F) C(PPR.PRR) != C(TPR.TRR)";)
1735 }
1736
1737 goto D;
1738
1739
1740
1741
1742
1743
1744
1745 G:;
1746
1747 DBGAPP ("do_append_cycle(G)\n");
1748
1749
1750 if (((cpu.TPR.CA >> 4) & 037777) > cpu.SDW->BOUND)
1751 {
1752 DBGAPP ("ACV15\n");
1753 DBGAPP ("do_append_cycle(G) ACV15\n");
1754 cpu.acvFaults |= ACV15;
1755 PNL (L68_ (cpu.apu.state |= apu_FLT;))
1756 FMSG (acvFaultsMsg = "acvFaults(G) C(TPR.CA)0,13 > SDW.BOUND";)
1757 DBGAPP ("acvFaults(G) C(TPR.CA)0,13 > SDW.BOUND\n"
1758 " CA %06o CA>>4 & 037777 %06o SDW->BOUND %06o",
1759 cpu.TPR.CA, ((cpu.TPR.CA >> 4) & 037777), cpu.SDW->BOUND);
1760 }
1761
1762 if (cpu.acvFaults)
1763 {
1764 DBGAPP ("do_append_cycle(G) acvFaults\n");
1765 PNL (L68_ (cpu.apu.state |= apu_FLT;))
1766
1767 doFault (FAULT_ACV, (_fault_subtype) {.fault_acv_subtype=cpu.acvFaults},
1768 "ACV fault");
1769 }
1770
1771
1772 if (cpu.SDW->U)
1773 goto H;
1774
1775
1776
1777
1778 DBGAPP ("do_append_cycle(G) CA %06o\n", cpu.TPR.CA);
1779 if (nomatch ||
1780 ! fetch_ptw_from_ptwam (cpu.SDW->POINTER, cpu.TPR.CA))
1781 {
1782 fetch_ptw (cpu.SDW, cpu.TPR.CA);
1783 if (! cpu.PTW0.DF)
1784 {
1785 if (thisCycle != ABSA_CYCLE)
1786 {
1787
1788 doFault (FAULT_DF0 + cpu.PTW0.FC, (_fault_subtype) {.bits=0},
1789 "PTW0.F == 0");
1790 }
1791 }
1792 loadPTWAM (cpu.SDW->POINTER, cpu.TPR.CA, nomatch);
1793 }
1794
1795
1796
1797
1798
1799
1800 if (i->opcodeX && ((i->opcode & 0770)== 0200|| (i->opcode & 0770) == 0220
1801 || (i->opcode & 0770)== 020|| (i->opcode & 0770) == 0300))
1802 {
1803 do_ptw2 (cpu.SDW, cpu.TPR.CA);
1804 }
1805 goto I;
1806
1807
1808
1809
1810
1811
1812
1813 H:;
1814 DBGAPP ("do_append_cycle(H): FANP\n");
1815
1816 PNL (L68_ (cpu.apu.state |= apu_FANP;))
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826 set_apu_status (apuStatus_FANP);
1827
1828 DBGAPP ("do_append_cycle(H): SDW->ADDR=%08o CA=%06o \n",
1829 cpu.SDW->ADDR, cpu.TPR.CA);
1830
1831 if (thisCycle == RTCD_OPERAND_FETCH &&
1832 get_addr_mode () == ABSOLUTE_mode &&
1833 ! (cpu.cu.XSF || cpu.currentInstruction.b29) )
1834 {
1835 finalAddress = cpu.TPR.CA;
1836 }
1837 else
1838 {
1839 finalAddress = (cpu.SDW->ADDR & 077777760) + cpu.TPR.CA;
1840 finalAddress &= 0xffffff;
1841 }
1842 PNL (cpu.APUMemAddr = finalAddress;)
1843
1844 DBGAPP ("do_append_cycle(H:FANP): (%05o:%06o) finalAddress=%08o\n",
1845 cpu.TPR.TSR, cpu.TPR.CA, finalAddress);
1846
1847
1848
1849 goto HI;
1850
1851 I:;
1852
1853
1854
1855 DBGAPP ("do_append_cycle(I): FAP\n");
1856 # ifdef LOCKLESS
1857 if ((StrOp ||
1858 thisCycle == OPERAND_RMW ||
1859 thisCycle == APU_DATA_RMW) && cpu.PTW->M == 0)
1860 # else
1861 if (StrOp && cpu.PTW->M == 0)
1862 # endif
1863 {
1864 modify_ptw (cpu.SDW, cpu.TPR.CA);
1865 }
1866
1867
1868 set_apu_status (apuStatus_FAP);
1869 PNL (L68_ (cpu.apu.state |= apu_FAP;))
1870
1871 word24 y2 = cpu.TPR.CA % 1024;
1872
1873
1874
1875 finalAddress = (((word24)cpu.PTW->ADDR & 0777760) << 6) + y2;
1876 finalAddress &= 0xffffff;
1877 PNL (cpu.APUMemAddr = finalAddress;)
1878
1879 L68_ (if (cpu.MR_cache.emr && cpu.MR_cache.ihr)
1880 add_l68_APU_history (APUH_FAP);)
1881
1882 DBGAPP ("do_append_cycle(H:FAP): (%05o:%06o) finalAddress=%08o\n",
1883 cpu.TPR.TSR, cpu.TPR.CA, finalAddress);
1884
1885
1886
1887 goto HI;
1888
1889 HI:
1890 DBGAPP ("do_append_cycle(HI)\n");
1891
1892
1893 if (thisCycle != ABSA_CYCLE)
1894 {
1895 cpu.cu.XSF = 1;
1896 sim_debug (DBG_TRACEEXT, & cpu_dev, "loading of cpu.TPR.TSR sets XSF to 1\n");
1897 }
1898
1899 if (thisCycle == OPERAND_STORE && cpu.useZone)
1900 {
1901 core_write_zone (finalAddress, * data, str_pct (thisCycle));
1902 }
1903 else if (StrOp)
1904 {
1905 core_writeN (finalAddress, data, nWords, str_pct (thisCycle));
1906 }
1907 else
1908 {
1909 # ifdef LOCKLESS
1910 if ((thisCycle == OPERAND_RMW || thisCycle == APU_DATA_RMW) && nWords == 1)
1911 {
1912 core_read_lock (finalAddress, data, str_pct (thisCycle));
1913 }
1914 else
1915 {
1916 if (thisCycle == OPERAND_RMW || thisCycle == APU_DATA_RMW)
1917 sim_warn("do_append_cycle: RMW nWords %d !=1\n", nWords);
1918 core_readN (finalAddress, data, nWords, str_pct (thisCycle));
1919 }
1920 # else
1921 if (thisCycle != ABSA_CYCLE)
1922 core_readN (finalAddress, data, nWords, str_pct (thisCycle));
1923 # endif
1924 }
1925
1926
1927 if (thisCycle == INDIRECT_WORD_FETCH)
1928 goto J;
1929
1930
1931 if (thisCycle == RTCD_OPERAND_FETCH)
1932 goto K;
1933
1934
1935 if (thisCycle == OPERAND_READ && (i->info->flags & CALL6_INS))
1936 goto N;
1937
1938
1939 if (thisCycle == INSTRUCTION_FETCH ||
1940 (thisCycle == OPERAND_READ && (i->info->flags & TRANSFER_INS)))
1941 goto L;
1942
1943
1944
1945 goto Exit;
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955 J:;
1956 DBGAPP ("do_append_cycle(J)\n");
1957
1958
1959 word6 tag = GET_TAG (IWB_IRODD);
1960 if ((GET_TM (tag) == TM_IR || GET_TM (tag) == TM_RI) &&
1961 (cpu.TPR.CA & 1) == 0)
1962 {
1963 if (ISITS (* data))
1964 goto O;
1965 if (ISITP (* data))
1966 goto P;
1967 }
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002 if ((* data) & 060)
2003
2004 {
2005
2006
2007
2008
2009
2010
2011
2012 }
2013
2014 goto Exit;
2015
2016
2017
2018
2019
2020
2021
2022 K:;
2023 DBGAPP ("do_append_cycle(K)\n");
2024
2025 word3 y = GET_ITS_RN (data);
2026
2027
2028
2029 cpu.TPR.TSR = GET_ITS_SEGNO (data);
2030
2031
2032
2033
2034 cpu.PPR.PRR = cpu.TPR.TRR = max3 (y, cpu.TPR.TRR, cpu.RSDWH_R1);
2035
2036
2037
2038 cpu.TPR.CA = GET_ITS_WORDNO (data);
2039
2040
2041
2042
2043
2044 goto KL;
2045
2046 L:;
2047
2048 DBGAPP ("do_append_cycle(L)\n");
2049
2050
2051 if (thisCycle == OPERAND_READ && (i->info->flags & TSPN_INS))
2052 {
2053
2054 if (i->opcode <= 0273)
2055 n = (i->opcode & 3);
2056 else
2057 n = (i->opcode & 3) + 4;
2058
2059
2060
2061
2062
2063 cpu.PR[n].RNR = cpu.PPR.PRR;
2064
2065
2066 if (get_addr_mode () == APPEND_mode)
2067 cpu.PR[n].SNR = cpu.PPR.PSR;
2068 cpu.PR[n].WORDNO = (cpu.PPR.IC + 1) & MASK18;
2069 SET_PR_BITNO (n, 0);
2070 # ifdef TESTING
2071 HDBGRegPRW (n, "app tspn");
2072 # endif
2073 }
2074
2075
2076
2077 if (thisCycle == INSTRUCTION_FETCH &&
2078 i->opcode == 0610 && ! i->opcodeX)
2079 {
2080
2081
2082 CPTUR (cptUsePRn + 0);
2083 CPTUR (cptUsePRn + 1);
2084 CPTUR (cptUsePRn + 2);
2085 CPTUR (cptUsePRn + 3);
2086 CPTUR (cptUsePRn + 4);
2087 CPTUR (cptUsePRn + 5);
2088 CPTUR (cptUsePRn + 6);
2089 CPTUR (cptUsePRn + 7);
2090 cpu.PR[0].RNR =
2091 cpu.PR[1].RNR =
2092 cpu.PR[2].RNR =
2093 cpu.PR[3].RNR =
2094 cpu.PR[4].RNR =
2095 cpu.PR[5].RNR =
2096 cpu.PR[6].RNR =
2097 cpu.PR[7].RNR = cpu.TPR.TRR;
2098 # ifdef TESTING
2099 HDBGRegPRW (0, "app rtcd");
2100 HDBGRegPRW (1, "app rtcd");
2101 HDBGRegPRW (2, "app rtcd");
2102 HDBGRegPRW (3, "app rtcd");
2103 HDBGRegPRW (4, "app rtcd");
2104 HDBGRegPRW (5, "app rtcd");
2105 HDBGRegPRW (6, "app rtcd");
2106 HDBGRegPRW (7, "app rtcd");
2107 # endif
2108 }
2109 goto KL;
2110
2111 KL:
2112 DBGAPP ("do_append_cycle(KL)\n");
2113
2114
2115 cpu.PPR.PSR = cpu.TPR.TSR;
2116
2117 cpu.PPR.IC = cpu.TPR.CA;
2118
2119 goto M;
2120
2121 M:
2122 DBGAPP ("do_append_cycle(M)\n");
2123
2124
2125 if (cpu.TPR.TRR == 0)
2126 {
2127
2128 cpu.PPR.P = cpu.SDW->P;
2129 }
2130 else
2131 {
2132
2133 cpu.PPR.P = 0;
2134 }
2135
2136 goto Exit;
2137
2138 N:
2139 DBGAPP ("do_append_cycle(N)\n");
2140
2141
2142 if (cpu.TPR.TRR == cpu.PPR.PRR)
2143 {
2144
2145 cpu.PR[7].SNR = cpu.PR[6].SNR;
2146 DBGAPP ("do_append_cycle(N) PR7.SNR = PR6.SNR %05o\n", cpu.PR[7].SNR);
2147 }
2148 else
2149 {
2150
2151 cpu.PR[7].SNR = ((word15) (cpu.DSBR.STACK << 3)) | cpu.TPR.TRR;
2152 DBGAPP ("do_append_cycle(N) STACK %05o TRR %o\n",
2153 cpu.DSBR.STACK, cpu.TPR.TRR);
2154 DBGAPP ("do_append_cycle(N) PR7.SNR = STACK||TRR %05o\n", cpu.PR[7].SNR);
2155 }
2156
2157
2158 cpu.PR[7].RNR = cpu.TPR.TRR;
2159
2160 cpu.PR[7].WORDNO = 0;
2161
2162 SET_PR_BITNO (7, 0);
2163 # ifdef TESTING
2164 HDBGRegPRW (7, "app call6");
2165 # endif
2166
2167 cpu.PPR.PRR = cpu.TPR.TRR;
2168
2169 cpu.PPR.PSR = cpu.TPR.TSR;
2170
2171 cpu.PPR.IC = cpu.TPR.CA;
2172
2173 goto M;
2174
2175
2176
2177
2178
2179
2180
2181 O:;
2182 DBGAPP ("do_append_cycle(O)\n");
2183 word3 its_RNR = GET_ITS_RN (data);
2184 DBGAPP ("do_append_cycle(O) TRR %o RSDWH.R1 %o ITS.RNR %o\n",
2185 cpu.TPR.TRR, cpu.RSDWH_R1, its_RNR);
2186
2187
2188
2189 cpu.TPR.TRR = max3 (its_RNR, cpu.TPR.TRR, cpu.RSDWH_R1);
2190 DBGAPP ("do_append_cycle(O) Set TRR to %o\n", cpu.TPR.TRR);
2191
2192 goto Exit;
2193
2194 P:;
2195
2196 DBGAPP ("do_append_cycle(P)\n");
2197
2198 n = GET_ITP_PRNUM (data);
2199 DBGAPP ("do_append_cycle(P) TRR %o RSDWH.R1 %o PR[n].RNR %o\n",
2200 cpu.TPR.TRR, cpu.RSDWH_R1, cpu.PR[n].RNR);
2201
2202
2203
2204 cpu.TPR.TRR = max3 (cpu.PR[n].RNR, cpu.TPR.TRR, cpu.RSDWH_R1);
2205 DBGAPP ("do_append_cycle(P) Set TRR to %o\n", cpu.TPR.TRR);
2206
2207 goto Exit;
2208
2209 Exit:;
2210
2211 PNL (cpu.APUDataBusOffset = cpu.TPR.CA;)
2212 PNL (cpu.APUDataBusAddr = finalAddress;)
2213
2214 PNL (L68_ (cpu.apu.state |= apu_FA;))
2215
2216 DBGAPP ("do_append_cycle (Exit) PRR %o PSR %05o P %o IC %06o\n",
2217 cpu.PPR.PRR, cpu.PPR.PSR, cpu.PPR.P, cpu.PPR.IC);
2218 DBGAPP ("do_append_cycle (Exit) TRR %o TSR %05o TBR %02o CA %06o\n",
2219 cpu.TPR.TRR, cpu.TPR.TSR, cpu.TPR.TBR, cpu.TPR.CA);
2220
2221 return finalAddress;
2222 }
2223 #endif
2224
2225
2226
2227
2228 #ifdef TESTING
2229 int dbgLookupAddress (word18 segno, word18 offset, word24 * finalAddress,
2230 char * * msg)
2231 {
2232
2233
2234 ptw_s PTW1;
2235 sdw_s SDW1;
2236
2237 if (2u * segno >= 16u * (cpu.DSBR.BND + 1u))
2238 {
2239 if (msg)
2240 * msg = "DSBR boundary violation.";
2241 return 1;
2242 }
2243
2244 if (cpu.DSBR.U == 0)
2245 {
2246
2247
2248 word24 y1 = (2 * segno) % 1024;
2249 word24 x1 = (2 * segno) / 1024;
2250
2251 word36 PTWx1;
2252 core_read ((cpu.DSBR.ADDR + x1) & PAMASK, & PTWx1, __func__);
2253
2254 PTW1.ADDR = GETHI (PTWx1);
2255 PTW1.U = TSTBIT (PTWx1, 9);
2256 PTW1.M = TSTBIT (PTWx1, 6);
2257 PTW1.DF = TSTBIT (PTWx1, 2);
2258 PTW1.FC = PTWx1 & 3;
2259
2260 if (! PTW1.DF)
2261 {
2262 if (msg)
2263 * msg = "!PTW0.F";
2264 return 2;
2265 }
2266
2267
2268
2269 y1 = (2 * segno) % 1024;
2270
2271 word36 SDWeven, SDWodd;
2272
2273 core_read2 (((((word24)PTW1. ADDR & 0777760) << 6) + y1) & PAMASK,
2274 & SDWeven, & SDWodd, __func__);
2275
2276
2277 SDW1.ADDR = (SDWeven >> 12) & 077777777;
2278 SDW1.R1 = (SDWeven >> 9) & 7;
2279 SDW1.R2 = (SDWeven >> 6) & 7;
2280 SDW1.R3 = (SDWeven >> 3) & 7;
2281 SDW1.DF = TSTBIT (SDWeven, 2);
2282 SDW1.FC = SDWeven & 3;
2283
2284
2285 SDW1.BOUND = (SDWodd >> 21) & 037777;
2286 SDW1.R = TSTBIT (SDWodd, 20);
2287 SDW1.E = TSTBIT (SDWodd, 19);
2288 SDW1.W = TSTBIT (SDWodd, 18);
2289 SDW1.P = TSTBIT (SDWodd, 17);
2290 SDW1.U = TSTBIT (SDWodd, 16);
2291 SDW1.G = TSTBIT (SDWodd, 15);
2292 SDW1.C = TSTBIT (SDWodd, 14);
2293 SDW1.EB = SDWodd & 037777;
2294 }
2295 else
2296 {
2297
2298
2299 word36 SDWeven, SDWodd;
2300
2301 core_read2 ((cpu.DSBR.ADDR + 2 * segno) & PAMASK,
2302 & SDWeven, & SDWodd, __func__);
2303
2304
2305 SDW1.ADDR = (SDWeven >> 12) & 077777777;
2306 SDW1.R1 = (SDWeven >> 9) & 7;
2307 SDW1.R2 = (SDWeven >> 6) & 7;
2308 SDW1.R3 = (SDWeven >> 3) & 7;
2309 SDW1.DF = TSTBIT (SDWeven, 2);
2310 SDW1.FC = SDWeven & 3;
2311
2312
2313 SDW1.BOUND = (SDWodd >> 21) & 037777;
2314 SDW1.R = TSTBIT (SDWodd, 20);
2315 SDW1.E = TSTBIT (SDWodd, 19);
2316 SDW1.W = TSTBIT (SDWodd, 18);
2317 SDW1.P = TSTBIT (SDWodd, 17);
2318 SDW1.U = TSTBIT (SDWodd, 16);
2319 SDW1.G = TSTBIT (SDWodd, 15);
2320 SDW1.C = TSTBIT (SDWodd, 14);
2321 SDW1.EB = SDWodd & 037777;
2322
2323 }
2324
2325 if (SDW1.DF == 0)
2326 {
2327 if (msg)
2328 * msg = "!SDW0.F != 0";
2329 return 3;
2330 }
2331
2332 if (((offset >> 4) & 037777) > SDW1.BOUND)
2333 {
2334 if (msg)
2335 * msg = "C(TPR.CA)0,13 > SDW.BOUND";
2336 return 4;
2337 }
2338
2339
2340 if (SDW1.U)
2341 {
2342 * finalAddress = (SDW1.ADDR + offset) & PAMASK;
2343 }
2344 else
2345 {
2346
2347 word24 y2 = offset % 1024;
2348 word24 x2 = (offset) / 1024;
2349
2350 word36 PTWx2;
2351
2352 core_read ((SDW1.ADDR + x2) & PAMASK, & PTWx2, __func__);
2353
2354 PTW1.ADDR = GETHI (PTWx2);
2355 PTW1.U = TSTBIT (PTWx2, 9);
2356 PTW1.M = TSTBIT (PTWx2, 6);
2357 PTW1.DF = TSTBIT (PTWx2, 2);
2358 PTW1.FC = PTWx2 & 3;
2359
2360 if (! PTW1.DF)
2361 {
2362 if (msg)
2363 * msg = "!PTW0.F";
2364 return 5;
2365 }
2366
2367 y2 = offset % 1024;
2368
2369 * finalAddress = ((((word24)PTW1.ADDR & 0777760) << 6) + y2) & PAMASK;
2370 }
2371 if (msg)
2372 * msg = "";
2373 return 0;
2374 }
2375 #endif