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
- 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 static char *str_pct (processor_cycle_type t)
1047 {
1048 switch (t)
1049 {
1050 case UNKNOWN_CYCLE: return "UNKNOWN_CYCLE";
1051 case OPERAND_STORE: return "OPERAND_STORE";
1052 case OPERAND_READ: return "OPERAND_READ";
1053 case INDIRECT_WORD_FETCH: return "INDIRECT_WORD_FETCH";
1054 case RTCD_OPERAND_FETCH: return "RTCD_OPERAND_FETCH";
1055 case INSTRUCTION_FETCH: return "INSTRUCTION_FETCH";
1056 case APU_DATA_READ: return "APU_DATA_READ";
1057 case APU_DATA_STORE: return "APU_DATA_STORE";
1058 case ABSA_CYCLE: return "ABSA_CYCLE";
1059 #ifdef LOCKLESS
1060 case OPERAND_RMW: return "OPERAND_RMW";
1061 case APU_DATA_RMW: return "APU_DATA_RMW";
1062 #endif
1063
1064 default:
1065 return "Unhandled processor_cycle_type";
1066 }
1067 }
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
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 word24 do_append_cycle (processor_cycle_type thisCycle, word36 * data,
1145 uint nWords)
1146 {
1147 DCDstruct * i = & cpu.currentInstruction;
1148 DBGAPP ("do_append_cycle(Entry) thisCycle=%s\n",
1149 str_pct (thisCycle));
1150 DBGAPP ("do_append_cycle(Entry) lastCycle=%s\n",
1151 str_pct (cpu.apu.lastCycle));
1152 DBGAPP ("do_append_cycle(Entry) CA %06o\n",
1153 cpu.TPR.CA);
1154 DBGAPP ("do_append_cycle(Entry) n=%2u\n",
1155 nWords);
1156 DBGAPP ("do_append_cycle(Entry) PPR.PRR=%o PPR.PSR=%05o\n",
1157 cpu.PPR.PRR, cpu.PPR.PSR);
1158 DBGAPP ("do_append_cycle(Entry) TPR.TRR=%o TPR.TSR=%05o\n",
1159 cpu.TPR.TRR, cpu.TPR.TSR);
1160
1161 if (i->b29)
1162 {
1163 DBGAPP ("do_append_cycle(Entry) isb29 PRNO %o\n",
1164 GET_PRN (IWB_IRODD));
1165 }
1166
1167 bool StrOp = (thisCycle == OPERAND_STORE ||
1168 thisCycle == APU_DATA_STORE);
1169
1170 bool nomatch = true;
1171 if (cpu.tweaks.enable_wam)
1172 {
1173
1174
1175
1176
1177
1178 nomatch = ((i->opcode == 0232 || i->opcode == 0254 ||
1179 i->opcode == 0154 || i->opcode == 0173) && i->opcodeX) ||
1180 ((i->opcode == 0557 || i->opcode == 0257) && ! i->opcodeX);
1181 }
1182
1183 processor_cycle_type lastCycle = cpu.apu.lastCycle;
1184 cpu.apu.lastCycle = thisCycle;
1185
1186 DBGAPP ("do_append_cycle(Entry) XSF %o\n", cpu.cu.XSF);
1187
1188 PNL (L68_ (cpu.apu.state = 0;))
1189
1190 cpu.RSDWH_R1 = 0;
1191
1192 cpu.acvFaults = 0;
1193
1194
1195 #define FMSG(x)
1196 FMSG (char * acvFaultsMsg = "<unknown>";)
1197
1198 word24 finalAddress = (word24) -1;
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208 word3 n = 0;
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223 if (thisCycle == RTCD_OPERAND_FETCH &&
1224 get_addr_mode() == ABSOLUTE_mode &&
1225 ! (cpu.cu.XSF || cpu.currentInstruction.b29) )
1226 {
1227 cpu.TPR.TSR = 0;
1228 DBGAPP ("RTCD_OPERAND_FETCH ABSOLUTE mode set TSR %05o TRR %o\n",
1229 cpu.TPR.TSR, cpu.TPR.TRR);
1230 }
1231
1232 goto A;
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244 A:;
1245
1246
1247 PNL (cpu.APUMemAddr = cpu.TPR.CA;)
1248
1249 DBGAPP ("do_append_cycle(A)\n");
1250
1251
1252 if (nomatch || ! fetch_sdw_from_sdwam (cpu.TPR.TSR))
1253 {
1254
1255 DBGAPP ("do_append_cycle(A):SDW for segment %05o not in SDWAM\n",
1256 cpu.TPR.TSR);
1257
1258 DBGAPP ("do_append_cycle(A):DSBR.U=%o\n",
1259 cpu.DSBR.U);
1260
1261 if (cpu.DSBR.U == 0)
1262 {
1263 fetch_dsptw (cpu.TPR.TSR);
1264
1265 if (! cpu.PTW0.DF)
1266 doFault (FAULT_DF0 + cpu.PTW0.FC, fst_zero,
1267 "do_append_cycle(A): PTW0.F == 0");
1268
1269 if (! cpu.PTW0.U)
1270 modify_dsptw (cpu.TPR.TSR);
1271
1272 fetch_psdw (cpu.TPR.TSR);
1273 }
1274 else
1275 fetch_nsdw (cpu.TPR.TSR);
1276
1277 if (cpu.SDW0.DF == 0)
1278 {
1279 if (thisCycle != ABSA_CYCLE)
1280 {
1281 DBGAPP ("do_append_cycle(A): SDW0.F == 0! "
1282 "Initiating directed fault\n");
1283
1284 doFault (FAULT_DF0 + cpu.SDW0.FC, fst_zero, "SDW0.F == 0");
1285 }
1286 }
1287
1288 load_sdwam (cpu.TPR.TSR, nomatch);
1289 }
1290 DBGAPP ("do_append_cycle(A) R1 %o R2 %o R3 %o E %o\n",
1291 cpu.SDW->R1, cpu.SDW->R2, cpu.SDW->R3, cpu.SDW->E);
1292
1293
1294 cpu.RSDWH_R1 = cpu.SDW->R1;
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306 DBGAPP ("do_append_cycle(B)\n");
1307
1308
1309
1310
1311 if (! (cpu.SDW->R1 <= cpu.SDW->R2 && cpu.SDW->R2 <= cpu.SDW->R3))
1312 {
1313
1314 cpu.acvFaults |= ACV0;
1315 PNL (L68_ (cpu.apu.state |= apu_FLT;))
1316 FMSG (acvFaultsMsg = "acvFaults(B) C(SDW.R1) <= C(SDW.R2) <= "
1317 "C(SDW .R3)";)
1318 }
1319
1320
1321
1322
1323
1324
1325
1326 if (thisCycle == INSTRUCTION_FETCH &&
1327 i->opcode == 0610 && ! i->opcodeX)
1328 goto C;
1329 else if (lastCycle == RTCD_OPERAND_FETCH)
1330 sim_warn ("%s: lastCycle == RTCD_OPERAND_FETCH opcode %0#o\n", __func__, i->opcode);
1331
1332
1333
1334
1335
1336
1337
1338 if (thisCycle == OPERAND_READ && (i->info->flags & CALL6_INS))
1339 goto E;
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363 if (thisCycle == INSTRUCTION_FETCH ||
1364 (thisCycle == OPERAND_READ && (i->info->flags & TRANSFER_INS)))
1365 goto F;
1366
1367
1368
1369
1370
1371 #ifdef LOCKLESS
1372
1373
1374
1375 if (!StrOp || thisCycle == OPERAND_RMW || thisCycle == APU_DATA_RMW)
1376 #else
1377 if (!StrOp)
1378 #endif
1379 {
1380 DBGAPP ("do_append_cycle(B):!STR-OP\n");
1381
1382
1383
1384 if (cpu.TPR.TRR > cpu.SDW->R2)
1385 {
1386 DBGAPP ("ACV3\n");
1387 DBGAPP ("do_append_cycle(B) ACV3\n");
1388
1389 cpu.acvFaults |= ACV3;
1390 PNL (L68_ (cpu.apu.state |= apu_FLT;))
1391 FMSG (acvFaultsMsg = "acvFaults(B) C(TPR.TRR) > C(SDW .R2)";)
1392 }
1393
1394 if (cpu.SDW->R == 0)
1395 {
1396
1397 cpu.TPR.TRR = cpu.PPR.PRR;
1398
1399
1400 if (cpu.PPR.PSR != cpu.TPR.TSR)
1401 {
1402 DBGAPP ("ACV4\n");
1403 DBGAPP ("do_append_cycle(B) ACV4\n");
1404
1405 cpu.acvFaults |= ACV4;
1406 PNL (L68_ (cpu.apu.state |= apu_FLT;))
1407 FMSG (acvFaultsMsg = "acvFaults(B) C(PPR.PSR) = C(TPR.TSR)";)
1408 }
1409
1410
1411
1412
1413
1414
1415 }
1416 }
1417
1418
1419
1420
1421 #ifdef LOCKLESS
1422 if (StrOp || thisCycle == OPERAND_RMW || thisCycle == APU_DATA_RMW)
1423 #else
1424 if (StrOp)
1425 #endif
1426 {
1427 DBGAPP ("do_append_cycle(B):STR-OP\n");
1428
1429
1430 if (cpu.TPR.TSR == cpu.PPR.PSR)
1431 cpu.TPR.TRR = cpu.PPR.PRR;
1432
1433
1434 if (cpu.TPR.TRR > cpu.SDW->R1)
1435 {
1436 DBGAPP ("ACV5 TRR %o R1 %o\n",
1437 cpu.TPR.TRR, cpu.SDW->R1);
1438
1439 cpu.acvFaults |= ACV5;
1440 PNL (L68_ (cpu.apu.state |= apu_FLT;))
1441 FMSG (acvFaultsMsg = "acvFaults(B) C(TPR.TRR) > C(SDW .R1)";)
1442 }
1443
1444 if (! cpu.SDW->W)
1445 {
1446
1447 cpu.TPR.TRR = cpu.PPR.PRR;
1448
1449 DBGAPP ("ACV6\n");
1450
1451 cpu.acvFaults |= ACV6;
1452 PNL (L68_ (cpu.apu.state |= apu_FLT;))
1453 FMSG (acvFaultsMsg = "acvFaults(B) ACV6 = W-OFF";)
1454 }
1455
1456 }
1457 goto G;
1458
1459
1460
1461
1462
1463
1464
1465 C:;
1466 DBGAPP ("do_append_cycle(C)\n");
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476 if (cpu.TPR.TRR < cpu.SDW->R1 ||
1477 cpu.TPR.TRR > cpu.SDW->R2)
1478 {
1479 DBGAPP ("ACV1 c\n");
1480 DBGAPP ("acvFaults(C) ACV1 ! ( C(SDW .R1) %o <= C(TPR.TRR) %o <= C(SDW .R2) %o )\n",
1481 cpu.SDW->R1, cpu.TPR.TRR, cpu.SDW->R2);
1482
1483 cpu.acvFaults |= ACV1;
1484 PNL (L68_ (cpu.apu.state |= apu_FLT;))
1485 FMSG (acvFaultsMsg = "acvFaults(C) C(SDW.R1 > C(TPR.TRR) > C(SDW.R2)";)
1486 }
1487
1488 if (! cpu.SDW->E)
1489 {
1490 DBGAPP ("ACV2 a\n");
1491 DBGAPP ("do_append_cycle(C) ACV2\n");
1492
1493 cpu.acvFaults |= ACV2;
1494 PNL (L68_ (cpu.apu.state |= apu_FLT;))
1495 FMSG (acvFaultsMsg = "acvFaults(C) SDW.E";)
1496 }
1497 if (cpu.TPR.TRR > cpu.PPR.PRR)
1498 sim_warn ("rtcd: outbound call cpu.TPR.TRR %d cpu.PPR.PRR %d\n",
1499 cpu.TPR.TRR, cpu.PPR.PRR);
1500
1501 if (cpu.TPR.TRR < cpu.PPR.PRR)
1502 {
1503 DBGAPP ("ACV11\n");
1504 DBGAPP ("do_append_cycle(C) ACV11\n");
1505
1506 cpu.acvFaults |= ACV11;
1507 PNL (L68_ (cpu.apu.state |= apu_FLT;))
1508 FMSG (acvFaultsMsg = "acvFaults(C) TRR>=PRR";)
1509 }
1510
1511 D:;
1512 DBGAPP ("do_append_cycle(D)\n");
1513
1514
1515
1516
1517
1518 if (cpu.rRALR == 0)
1519 goto G;
1520
1521
1522 if (! (cpu.PPR.PRR < cpu.rRALR))
1523 {
1524 DBGAPP ("ACV13\n");
1525 DBGAPP ("acvFaults(D) C(PPR.PRR) %o < RALR %o\n",
1526 cpu.PPR.PRR, cpu.rRALR);
1527 cpu.acvFaults |= ACV13;
1528 PNL (L68_ (cpu.apu.state |= apu_FLT;))
1529 FMSG (acvFaultsMsg = "acvFaults(D) C(PPR.PRR) < RALR";)
1530 }
1531
1532 goto G;
1533
1534
1535
1536
1537
1538
1539
1540 E:;
1541
1542
1543
1544
1545
1546
1547 DBGAPP ("do_append_cycle(E): CALL6\n");
1548 DBGAPP ("do_append_cycle(E): E %o G %o PSR %05o TSR %05o CA %06o "
1549 "EB %06o R %o%o%o TRR %o PRR %o\n",
1550 cpu.SDW->E, cpu.SDW->G, cpu.PPR.PSR, cpu.TPR.TSR, cpu.TPR.CA,
1551 cpu.SDW->EB, cpu.SDW->R1, cpu.SDW->R2, cpu.SDW->R3,
1552 cpu.TPR.TRR, cpu.PPR.PRR);
1553
1554
1555 if (! cpu.SDW->E)
1556 {
1557 DBGAPP ("ACV2 b\n");
1558 DBGAPP ("do_append_cycle(E) ACV2\n");
1559
1560 cpu.acvFaults |= ACV2;
1561 PNL (L68_ (cpu.apu.state |= apu_FLT;))
1562 FMSG (acvFaultsMsg = "acvFaults(E) SDW .E set OFF";)
1563 }
1564
1565
1566 if (cpu.SDW->G)
1567 goto E1;
1568
1569
1570 if (cpu.PPR.PSR == cpu.TPR.TSR && ! TST_I_ABS)
1571 goto E1;
1572
1573
1574
1575
1576 if (cpu.TPR.CA >= (word18) cpu.SDW->EB)
1577 {
1578 DBGAPP ("ACV7\n");
1579 DBGAPP ("do_append_cycle(E) ACV7\n");
1580
1581 cpu.acvFaults |= ACV7;
1582 PNL (L68_ (cpu.apu.state |= apu_FLT;))
1583 FMSG (acvFaultsMsg = "acvFaults(E) TPR.CA4-17 >= SDW.CL";)
1584 }
1585
1586 E1:
1587 DBGAPP ("do_append_cycle(E1): CALL6 (cont'd)\n");
1588
1589
1590 if (cpu.TPR.TRR > cpu.SDW->R3)
1591 {
1592 DBGAPP ("ACV8\n");
1593 DBGAPP ("do_append_cycle(E) ACV8\n");
1594
1595 cpu.acvFaults |= ACV8;
1596 PNL (L68_ (cpu.apu.state |= apu_FLT;))
1597 FMSG (acvFaultsMsg = "acvFaults(E1) C(TPR.TRR) > SDW.R3";)
1598 }
1599
1600
1601 if (cpu.TPR.TRR < cpu.SDW->R1)
1602 {
1603 DBGAPP ("ACV9\n");
1604 DBGAPP ("do_append_cycle(E) ACV9\n");
1605
1606 cpu.acvFaults |= ACV9;
1607 PNL (L68_ (cpu.apu.state |= apu_FLT;))
1608 FMSG (acvFaultsMsg = "acvFaults(E1) C(TPR.TRR) < SDW.R1";)
1609 }
1610
1611
1612 if (cpu.TPR.TRR > cpu.PPR.PRR)
1613 {
1614
1615 if (cpu.PPR.PRR < cpu.SDW->R2)
1616 {
1617 DBGAPP ("ACV10\n");
1618 DBGAPP ("do_append_cycle(E) ACV10\n");
1619
1620 cpu.acvFaults |= ACV10;
1621 PNL (L68_ (cpu.apu.state |= apu_FLT;))
1622 FMSG (acvFaultsMsg = "acvFaults(E1) C(TPR.TRR) > C(PPR.PRR) && "
1623 "C(PPR.PRR) < SDW.R2";)
1624 }
1625 }
1626
1627 DBGAPP ("do_append_cycle(E1): CALL6 TPR.TRR %o SDW->R2 %o\n",
1628 cpu.TPR.TRR, cpu.SDW->R2);
1629
1630
1631 if (cpu.TPR.TRR > cpu.SDW->R2)
1632 {
1633
1634 cpu.TPR.TRR = cpu.SDW->R2;
1635 }
1636
1637 DBGAPP ("do_append_cycle(E1): CALL6 TPR.TRR %o\n", cpu.TPR.TRR);
1638
1639 goto G;
1640
1641
1642
1643
1644
1645
1646
1647 F:;
1648 PNL (L68_ (cpu.apu.state |= apu_PIAU;))
1649 DBGAPP ("do_append_cycle(F): transfer or instruction fetch\n");
1650
1651
1652
1653
1654
1655
1656
1657 if (cpu.TPR.TRR < cpu.SDW->R1 ||
1658 cpu.TPR.TRR > cpu.SDW->R2)
1659 {
1660 DBGAPP ("ACV1 a/b\n");
1661 DBGAPP ("acvFaults(F) ACV1 !( C(SDW .R1) %o <= C(TPR.TRR) %o <= C(SDW .R2) %o )\n",
1662 cpu.SDW->R1, cpu.TPR.TRR, cpu.SDW->R2);
1663 cpu.acvFaults |= ACV1;
1664 PNL (L68_ (cpu.apu.state |= apu_FLT;))
1665 FMSG (acvFaultsMsg = "acvFaults(F) C(TPR.TRR) < C(SDW .R1)";)
1666 }
1667
1668 if (! cpu.SDW->E)
1669 {
1670 DBGAPP ("ACV2 c \n");
1671 DBGAPP ("do_append_cycle(F) ACV2\n");
1672 cpu.acvFaults |= ACV2;
1673 PNL (L68_ (cpu.apu.state |= apu_FLT;))
1674 FMSG (acvFaultsMsg = "acvFaults(F) SDW .E set OFF";)
1675 }
1676
1677
1678 if (cpu.PPR.PRR != cpu.TPR.TRR)
1679 {
1680 DBGAPP ("ACV12\n");
1681 DBGAPP ("do_append_cycle(F) ACV12\n");
1682
1683 cpu.acvFaults |= ACV12;
1684 PNL (L68_ (cpu.apu.state |= apu_FLT;))
1685 FMSG (acvFaultsMsg = "acvFaults(F) C(PPR.PRR) != C(TPR.TRR)";)
1686 }
1687
1688 goto D;
1689
1690
1691
1692
1693
1694
1695
1696 G:;
1697
1698 DBGAPP ("do_append_cycle(G)\n");
1699
1700
1701 if (((cpu.TPR.CA >> 4) & 037777) > cpu.SDW->BOUND)
1702 {
1703 DBGAPP ("ACV15\n");
1704 DBGAPP ("do_append_cycle(G) ACV15\n");
1705 cpu.acvFaults |= ACV15;
1706 PNL (L68_ (cpu.apu.state |= apu_FLT;))
1707 FMSG (acvFaultsMsg = "acvFaults(G) C(TPR.CA)0,13 > SDW.BOUND";)
1708 DBGAPP ("acvFaults(G) C(TPR.CA)0,13 > SDW.BOUND\n"
1709 " CA %06o CA>>4 & 037777 %06o SDW->BOUND %06o",
1710 cpu.TPR.CA, ((cpu.TPR.CA >> 4) & 037777), cpu.SDW->BOUND);
1711 }
1712
1713 if (cpu.acvFaults)
1714 {
1715 DBGAPP ("do_append_cycle(G) acvFaults\n");
1716 PNL (L68_ (cpu.apu.state |= apu_FLT;))
1717
1718 doFault (FAULT_ACV, (_fault_subtype) {.fault_acv_subtype=cpu.acvFaults},
1719 "ACV fault");
1720 }
1721
1722
1723 if (cpu.SDW->U)
1724 goto H;
1725
1726
1727
1728
1729 DBGAPP ("do_append_cycle(G) CA %06o\n", cpu.TPR.CA);
1730 if (nomatch ||
1731 ! fetch_ptw_from_ptwam (cpu.SDW->POINTER, cpu.TPR.CA))
1732 {
1733 fetch_ptw (cpu.SDW, cpu.TPR.CA);
1734 if (! cpu.PTW0.DF)
1735 {
1736 if (thisCycle != ABSA_CYCLE)
1737 {
1738
1739 doFault (FAULT_DF0 + cpu.PTW0.FC, (_fault_subtype) {.bits=0},
1740 "PTW0.F == 0");
1741 }
1742 }
1743 loadPTWAM (cpu.SDW->POINTER, cpu.TPR.CA, nomatch);
1744 }
1745
1746
1747
1748
1749
1750
1751 if (i->opcodeX && ((i->opcode & 0770)== 0200|| (i->opcode & 0770) == 0220
1752 || (i->opcode & 0770)== 020|| (i->opcode & 0770) == 0300))
1753 {
1754 do_ptw2 (cpu.SDW, cpu.TPR.CA);
1755 }
1756 goto I;
1757
1758
1759
1760
1761
1762
1763
1764 H:;
1765 DBGAPP ("do_append_cycle(H): FANP\n");
1766
1767 PNL (L68_ (cpu.apu.state |= apu_FANP;))
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777 set_apu_status (apuStatus_FANP);
1778
1779 DBGAPP ("do_append_cycle(H): SDW->ADDR=%08o CA=%06o \n",
1780 cpu.SDW->ADDR, cpu.TPR.CA);
1781
1782 if (thisCycle == RTCD_OPERAND_FETCH &&
1783 get_addr_mode () == ABSOLUTE_mode &&
1784 ! (cpu.cu.XSF || cpu.currentInstruction.b29) )
1785 {
1786 finalAddress = cpu.TPR.CA;
1787 }
1788 else
1789 {
1790 finalAddress = (cpu.SDW->ADDR & 077777760) + cpu.TPR.CA;
1791 finalAddress &= 0xffffff;
1792 }
1793 PNL (cpu.APUMemAddr = finalAddress;)
1794
1795 DBGAPP ("do_append_cycle(H:FANP): (%05o:%06o) finalAddress=%08o\n",
1796 cpu.TPR.TSR, cpu.TPR.CA, finalAddress);
1797
1798
1799
1800 goto HI;
1801
1802 I:;
1803
1804
1805
1806 DBGAPP ("do_append_cycle(I): FAP\n");
1807 #ifdef LOCKLESS
1808 if ((StrOp ||
1809 thisCycle == OPERAND_RMW ||
1810 thisCycle == APU_DATA_RMW) && cpu.PTW->M == 0)
1811 #else
1812 if (StrOp && cpu.PTW->M == 0)
1813 #endif
1814 {
1815 modify_ptw (cpu.SDW, cpu.TPR.CA);
1816 }
1817
1818
1819 set_apu_status (apuStatus_FAP);
1820 PNL (L68_ (cpu.apu.state |= apu_FAP;))
1821
1822 word24 y2 = cpu.TPR.CA % 1024;
1823
1824
1825
1826 finalAddress = (((word24)cpu.PTW->ADDR & 0777760) << 6) + y2;
1827 finalAddress &= 0xffffff;
1828 PNL (cpu.APUMemAddr = finalAddress;)
1829
1830 L68_ (if (cpu.MR_cache.emr && cpu.MR_cache.ihr)
1831 add_l68_APU_history (APUH_FAP);)
1832 DBGAPP ("do_append_cycle(H:FAP): (%05o:%06o) finalAddress=%08o\n",
1833 cpu.TPR.TSR, cpu.TPR.CA, finalAddress);
1834
1835
1836
1837 goto HI;
1838
1839 HI:
1840 DBGAPP ("do_append_cycle(HI)\n");
1841
1842
1843 if (thisCycle != ABSA_CYCLE)
1844 {
1845 cpu.cu.XSF = 1;
1846 sim_debug (DBG_TRACEEXT, & cpu_dev, "loading of cpu.TPR.TSR sets XSF to 1\n");
1847 }
1848
1849 if (thisCycle == OPERAND_STORE && cpu.useZone)
1850 {
1851 core_write_zone (finalAddress, * data, str_pct (thisCycle));
1852 }
1853 else if (StrOp)
1854 {
1855 core_writeN (finalAddress, data, nWords, str_pct (thisCycle));
1856 }
1857 else
1858 {
1859 #ifdef LOCKLESS
1860 if ((thisCycle == OPERAND_RMW || thisCycle == APU_DATA_RMW) && nWords == 1)
1861 {
1862 core_read_lock (finalAddress, data, str_pct (thisCycle));
1863 }
1864 else
1865 {
1866 if (thisCycle == OPERAND_RMW || thisCycle == APU_DATA_RMW)
1867 sim_warn("do_append_cycle: RMW nWords %d !=1\n", nWords);
1868 core_readN (finalAddress, data, nWords, str_pct (thisCycle));
1869 }
1870 #else
1871 if (thisCycle != ABSA_CYCLE)
1872 core_readN (finalAddress, data, nWords, str_pct (thisCycle));
1873
1874 #endif
1875 }
1876
1877
1878 if (thisCycle == INDIRECT_WORD_FETCH)
1879 goto J;
1880
1881
1882 if (thisCycle == RTCD_OPERAND_FETCH)
1883 goto K;
1884
1885
1886 if (thisCycle == OPERAND_READ && (i->info->flags & CALL6_INS))
1887 goto N;
1888
1889
1890 if (thisCycle == INSTRUCTION_FETCH ||
1891 (thisCycle == OPERAND_READ && (i->info->flags & TRANSFER_INS)))
1892 goto L;
1893
1894
1895
1896 goto Exit;
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906 J:;
1907 DBGAPP ("do_append_cycle(J)\n");
1908
1909
1910 word6 tag = GET_TAG (IWB_IRODD);
1911 if ((GET_TM (tag) == TM_IR || GET_TM (tag) == TM_RI) &&
1912 (cpu.TPR.CA & 1) == 0)
1913 {
1914 if (ISITS (* data))
1915 goto O;
1916 if (ISITP (* data))
1917 goto P;
1918 }
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953 if ((* data) & 060)
1954
1955 {
1956
1957
1958
1959
1960
1961
1962
1963 }
1964
1965 goto Exit;
1966
1967
1968
1969
1970
1971
1972
1973 K:;
1974 DBGAPP ("do_append_cycle(K)\n");
1975
1976 word3 y = GET_ITS_RN (data);
1977
1978
1979
1980 cpu.TPR.TSR = GET_ITS_SEGNO (data);
1981
1982
1983
1984
1985 cpu.PPR.PRR = cpu.TPR.TRR = max3 (y, cpu.TPR.TRR, cpu.RSDWH_R1);
1986
1987
1988
1989 cpu.TPR.CA = GET_ITS_WORDNO (data);
1990
1991
1992
1993
1994
1995 goto KL;
1996
1997 L:;
1998
1999 DBGAPP ("do_append_cycle(L)\n");
2000
2001
2002 if (thisCycle == OPERAND_READ && (i->info->flags & TSPN_INS))
2003 {
2004
2005 if (i->opcode <= 0273)
2006 n = (i->opcode & 3);
2007 else
2008 n = (i->opcode & 3) + 4;
2009
2010
2011
2012
2013
2014 cpu.PR[n].RNR = cpu.PPR.PRR;
2015
2016
2017 if (get_addr_mode () == APPEND_mode)
2018 cpu.PR[n].SNR = cpu.PPR.PSR;
2019 cpu.PR[n].WORDNO = (cpu.PPR.IC + 1) & MASK18;
2020 SET_PR_BITNO (n, 0);
2021 #ifdef TESTING
2022 HDBGRegPRW (n, "app tspn");
2023 #endif
2024 }
2025
2026
2027
2028 if (thisCycle == INSTRUCTION_FETCH &&
2029 i->opcode == 0610 && ! i->opcodeX)
2030 {
2031
2032
2033 CPTUR (cptUsePRn + 0);
2034 CPTUR (cptUsePRn + 1);
2035 CPTUR (cptUsePRn + 2);
2036 CPTUR (cptUsePRn + 3);
2037 CPTUR (cptUsePRn + 4);
2038 CPTUR (cptUsePRn + 5);
2039 CPTUR (cptUsePRn + 6);
2040 CPTUR (cptUsePRn + 7);
2041 cpu.PR[0].RNR =
2042 cpu.PR[1].RNR =
2043 cpu.PR[2].RNR =
2044 cpu.PR[3].RNR =
2045 cpu.PR[4].RNR =
2046 cpu.PR[5].RNR =
2047 cpu.PR[6].RNR =
2048 cpu.PR[7].RNR = cpu.TPR.TRR;
2049 #ifdef TESTING
2050 HDBGRegPRW (0, "app rtcd");
2051 HDBGRegPRW (1, "app rtcd");
2052 HDBGRegPRW (2, "app rtcd");
2053 HDBGRegPRW (3, "app rtcd");
2054 HDBGRegPRW (4, "app rtcd");
2055 HDBGRegPRW (5, "app rtcd");
2056 HDBGRegPRW (6, "app rtcd");
2057 HDBGRegPRW (7, "app rtcd");
2058 #endif
2059 }
2060 goto KL;
2061
2062 KL:
2063 DBGAPP ("do_append_cycle(KL)\n");
2064
2065
2066 cpu.PPR.PSR = cpu.TPR.TSR;
2067
2068 cpu.PPR.IC = cpu.TPR.CA;
2069
2070 goto M;
2071
2072 M:
2073 DBGAPP ("do_append_cycle(M)\n");
2074
2075
2076 if (cpu.TPR.TRR == 0)
2077 {
2078
2079 cpu.PPR.P = cpu.SDW->P;
2080 }
2081 else
2082 {
2083
2084 cpu.PPR.P = 0;
2085 }
2086
2087 goto Exit;
2088
2089 N:
2090 DBGAPP ("do_append_cycle(N)\n");
2091
2092
2093 if (cpu.TPR.TRR == cpu.PPR.PRR)
2094 {
2095
2096 cpu.PR[7].SNR = cpu.PR[6].SNR;
2097 DBGAPP ("do_append_cycle(N) PR7.SNR = PR6.SNR %05o\n", cpu.PR[7].SNR);
2098 }
2099 else
2100 {
2101
2102 cpu.PR[7].SNR = ((word15) (cpu.DSBR.STACK << 3)) | cpu.TPR.TRR;
2103 DBGAPP ("do_append_cycle(N) STACK %05o TRR %o\n",
2104 cpu.DSBR.STACK, cpu.TPR.TRR);
2105 DBGAPP ("do_append_cycle(N) PR7.SNR = STACK||TRR %05o\n", cpu.PR[7].SNR);
2106 }
2107
2108
2109 cpu.PR[7].RNR = cpu.TPR.TRR;
2110
2111 cpu.PR[7].WORDNO = 0;
2112
2113 SET_PR_BITNO (7, 0);
2114 #ifdef TESTING
2115 HDBGRegPRW (7, "app call6");
2116 #endif
2117
2118 cpu.PPR.PRR = cpu.TPR.TRR;
2119
2120 cpu.PPR.PSR = cpu.TPR.TSR;
2121
2122 cpu.PPR.IC = cpu.TPR.CA;
2123
2124 goto M;
2125
2126
2127
2128
2129
2130
2131
2132 O:;
2133 DBGAPP ("do_append_cycle(O)\n");
2134 word3 its_RNR = GET_ITS_RN (data);
2135 DBGAPP ("do_append_cycle(O) TRR %o RSDWH.R1 %o ITS.RNR %o\n",
2136 cpu.TPR.TRR, cpu.RSDWH_R1, its_RNR);
2137
2138
2139
2140 cpu.TPR.TRR = max3 (its_RNR, cpu.TPR.TRR, cpu.RSDWH_R1);
2141 DBGAPP ("do_append_cycle(O) Set TRR to %o\n", cpu.TPR.TRR);
2142
2143 goto Exit;
2144
2145 P:;
2146
2147 DBGAPP ("do_append_cycle(P)\n");
2148
2149 n = GET_ITP_PRNUM (data);
2150 DBGAPP ("do_append_cycle(P) TRR %o RSDWH.R1 %o PR[n].RNR %o\n",
2151 cpu.TPR.TRR, cpu.RSDWH_R1, cpu.PR[n].RNR);
2152
2153
2154
2155 cpu.TPR.TRR = max3 (cpu.PR[n].RNR, cpu.TPR.TRR, cpu.RSDWH_R1);
2156 DBGAPP ("do_append_cycle(P) Set TRR to %o\n", cpu.TPR.TRR);
2157
2158 goto Exit;
2159
2160 Exit:;
2161
2162 PNL (cpu.APUDataBusOffset = cpu.TPR.CA;)
2163 PNL (cpu.APUDataBusAddr = finalAddress;)
2164
2165 PNL (L68_ (cpu.apu.state |= apu_FA;))
2166
2167 DBGAPP ("do_append_cycle (Exit) PRR %o PSR %05o P %o IC %06o\n",
2168 cpu.PPR.PRR, cpu.PPR.PSR, cpu.PPR.P, cpu.PPR.IC);
2169 DBGAPP ("do_append_cycle (Exit) TRR %o TSR %05o TBR %02o CA %06o\n",
2170 cpu.TPR.TRR, cpu.TPR.TSR, cpu.TPR.TBR, cpu.TPR.CA);
2171
2172 return finalAddress;
2173 }
2174
2175
2176
2177
2178 #ifdef TESTING
2179 int dbgLookupAddress (word18 segno, word18 offset, word24 * finalAddress,
2180 char * * msg)
2181 {
2182
2183
2184 ptw_s PTW1;
2185 sdw_s SDW1;
2186
2187 if (2u * segno >= 16u * (cpu.DSBR.BND + 1u))
2188 {
2189 if (msg)
2190 * msg = "DSBR boundary violation.";
2191 return 1;
2192 }
2193
2194 if (cpu.DSBR.U == 0)
2195 {
2196
2197
2198 word24 y1 = (2 * segno) % 1024;
2199 word24 x1 = (2 * segno) / 1024;
2200
2201 word36 PTWx1;
2202 core_read ((cpu.DSBR.ADDR + x1) & PAMASK, & PTWx1, __func__);
2203
2204 PTW1.ADDR = GETHI (PTWx1);
2205 PTW1.U = TSTBIT (PTWx1, 9);
2206 PTW1.M = TSTBIT (PTWx1, 6);
2207 PTW1.DF = TSTBIT (PTWx1, 2);
2208 PTW1.FC = PTWx1 & 3;
2209
2210 if (! PTW1.DF)
2211 {
2212 if (msg)
2213 * msg = "!PTW0.F";
2214 return 2;
2215 }
2216
2217
2218
2219 y1 = (2 * segno) % 1024;
2220
2221 word36 SDWeven, SDWodd;
2222
2223 core_read2 (((((word24)PTW1. ADDR & 0777760) << 6) + y1) & PAMASK,
2224 & SDWeven, & SDWodd, __func__);
2225
2226
2227 SDW1.ADDR = (SDWeven >> 12) & 077777777;
2228 SDW1.R1 = (SDWeven >> 9) & 7;
2229 SDW1.R2 = (SDWeven >> 6) & 7;
2230 SDW1.R3 = (SDWeven >> 3) & 7;
2231 SDW1.DF = TSTBIT (SDWeven, 2);
2232 SDW1.FC = SDWeven & 3;
2233
2234
2235 SDW1.BOUND = (SDWodd >> 21) & 037777;
2236 SDW1.R = TSTBIT (SDWodd, 20);
2237 SDW1.E = TSTBIT (SDWodd, 19);
2238 SDW1.W = TSTBIT (SDWodd, 18);
2239 SDW1.P = TSTBIT (SDWodd, 17);
2240 SDW1.U = TSTBIT (SDWodd, 16);
2241 SDW1.G = TSTBIT (SDWodd, 15);
2242 SDW1.C = TSTBIT (SDWodd, 14);
2243 SDW1.EB = SDWodd & 037777;
2244 }
2245 else
2246 {
2247
2248
2249 word36 SDWeven, SDWodd;
2250
2251 core_read2 ((cpu.DSBR.ADDR + 2 * segno) & PAMASK,
2252 & SDWeven, & SDWodd, __func__);
2253
2254
2255 SDW1.ADDR = (SDWeven >> 12) & 077777777;
2256 SDW1.R1 = (SDWeven >> 9) & 7;
2257 SDW1.R2 = (SDWeven >> 6) & 7;
2258 SDW1.R3 = (SDWeven >> 3) & 7;
2259 SDW1.DF = TSTBIT (SDWeven, 2);
2260 SDW1.FC = SDWeven & 3;
2261
2262
2263 SDW1.BOUND = (SDWodd >> 21) & 037777;
2264 SDW1.R = TSTBIT (SDWodd, 20);
2265 SDW1.E = TSTBIT (SDWodd, 19);
2266 SDW1.W = TSTBIT (SDWodd, 18);
2267 SDW1.P = TSTBIT (SDWodd, 17);
2268 SDW1.U = TSTBIT (SDWodd, 16);
2269 SDW1.G = TSTBIT (SDWodd, 15);
2270 SDW1.C = TSTBIT (SDWodd, 14);
2271 SDW1.EB = SDWodd & 037777;
2272
2273 }
2274
2275 if (SDW1.DF == 0)
2276 {
2277 if (msg)
2278 * msg = "!SDW0.F != 0";
2279 return 3;
2280 }
2281
2282 if (((offset >> 4) & 037777) > SDW1.BOUND)
2283 {
2284 if (msg)
2285 * msg = "C(TPR.CA)0,13 > SDW.BOUND";
2286 return 4;
2287 }
2288
2289
2290 if (SDW1.U)
2291 {
2292 * finalAddress = (SDW1.ADDR + offset) & PAMASK;
2293 }
2294 else
2295 {
2296
2297 word24 y2 = offset % 1024;
2298 word24 x2 = (offset) / 1024;
2299
2300 word36 PTWx2;
2301
2302 core_read ((SDW1.ADDR + x2) & PAMASK, & PTWx2, __func__);
2303
2304 PTW1.ADDR = GETHI (PTWx2);
2305 PTW1.U = TSTBIT (PTWx2, 9);
2306 PTW1.M = TSTBIT (PTWx2, 6);
2307 PTW1.DF = TSTBIT (PTWx2, 2);
2308 PTW1.FC = PTWx2 & 3;
2309
2310 if (! PTW1.DF)
2311 {
2312 if (msg)
2313 * msg = "!PTW0.F";
2314 return 5;
2315 }
2316
2317 y2 = offset % 1024;
2318
2319 * finalAddress = ((((word24)PTW1.ADDR & 0777760) << 6) + y2) & PAMASK;
2320 }
2321 if (msg)
2322 * msg = "";
2323 return 0;
2324 }
2325 #endif