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