root/src/dps8/doAppendCycleInstructionFetch.h

/* [previous][next][first][last][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. doAppendCycleInstructionFetch

   1 /*
   2  * vim: filetype=c:tabstop=4:ai:expandtab
   3  * SPDX-License-Identifier: ICU
   4  * scspell-id: 45d63e9a-171d-11ee-b7ed-80ee73e9b8e7
   5  *
   6  * ---------------------------------------------------------------------------
   7  *
   8  * Copyright (c) 2022-2023 Charles Anthony
   9  * Copyright (c) 2022-2023 Jeffrey H. Johnson
  10  * Copyright (c) 2022-2025 The DPS8M Development Team
  11  *
  12  * This software is made available under the terms of the ICU License.
  13  * See the LICENSE.md file at the top-level directory of this distribution.
  14  *
  15  * ---------------------------------------------------------------------------
  16  */
  17 
  18 // L68: the APU status of an instruction fetch append cycle keeps PI-AP
  19 // with FAP/FANP; a fault then stores both in SCU word 0 (PA865 01A, PA885)
  20 #define L68_PI_AP \
  21   do { if (cpu.tweaks.l68_mode) cpu.cu.APUCycleBits |= 04000; } while (0)
  22 
  23 //
  24 //    A get SDW
  25 //       |
  26 //       V
  27 //    B last cycle = RTCD operand fetch?
  28 //       Yes                            No
  29 //        |                              |
  30 //        V                              V
  31 //    C check ring brackets           F check ring brackets
  32 //        |                              |
  33 //        +------------------------------+
  34 //        |
  35 //        V
  36 //    D check RALR
  37 //        |
  38 //        V
  39 //    G check bound
  40 //      paged?
  41 //       Yes                            No
  42 //        |                              |
  43 //        V                              |
  44 //    G1 get PTW                         |
  45 //        |                              |
  46 //        V                              V
  47 //    I calc. paged address           H calc. unpaged address
  48 //        |                              |
  49 //        +------------------------------+
  50 //        |
  51 //        V
  52 //    HI set XSF
  53 //       read memory
  54 //        |
  55 //        V
  56 //    L lastcyle RTCD operand fetch handling
  57 //        |
  58 //        V
  59 //    KL set PSR, IC
  60 //        |
  61 //        V
  62 //    M  set P
  63 //        |
  64 //        V
  65 //    EXIT  return final address
  66 
  67 word24 doAppendCycleInstructionFetch (cpu_state_t * cpup, word36 * data, uint nWords) {
     /* [previous][next][first][last][top][bottom][index][help] */
  68 //sim_printf ("doAppendCycleInstructionFetch %05o:%06o\r\n",
  69 static int evcnt = 0;
  70   DCDstruct * i = & cpu.currentInstruction;
  71   (void)evcnt;
  72   DBGAPP ("doAppendCycleInstructionFetch(Entry) thisCycle=INSTRUCTION_FETCH\r\n");
  73   DBGAPP ("doAppendCycleInstructionFetch(Entry) lastCycle=%s\r\n", str_pct (cpu.apu.lastCycle));
  74   DBGAPP ("doAppendCycleInstructionFetch(Entry) CA %06o\r\n", cpu.TPR.CA);
  75   DBGAPP ("doAppendCycleInstructionFetch(Entry) n=%2u\r\n", nWords);
  76   DBGAPP ("doAppendCycleInstructionFetch(Entry) PPR.PRR=%o PPR.PSR=%05o\r\n", cpu.PPR.PRR, cpu.PPR.PSR);
  77   DBGAPP ("doAppendCycleInstructionFetch(Entry) TPR.TRR=%o TPR.TSR=%05o\r\n", cpu.TPR.TRR, cpu.TPR.TSR);
  78 
  79   if (i->b29) {
  80     DBGAPP ("doAppendCycleInstructionFetch(Entry) isb29 PRNO %o\r\n", GET_PRN (IWB_IRODD));
  81   }
  82 
  83   uint this = UC_INSTRUCTION_FETCH;
  84 
  85   word24 finalAddress = 0;
  86   word24 pageAddress = 0;
  87   word3 RSDWH_R1 = 0;
  88   word14 bound = 0;
  89   word1 p = 0;
  90   bool paged = false;
  91 
  92 // ucache logic:
  93 // The cache will hit if:
  94 //   No CAMS/CAMP instruction has been executed.
  95 //   The segment number matches the cached value.
  96 //   The offset is on the same page as the cached value.
  97 //
  98 // doAppendCycle (INSTRUCTION_FETCH) checks:
  99 //   associative memory: Don't Care. If the cache hits, the WAM won't be
 100 //     queried which is the best case condition.
 101 //   lastCycle: Set to INSTRUCTION_FETCH.
 102 //   RSDWH_R1: Restored from cache.
 103 //   lastCycle == RTCD_OPERAND_FETCH. One would think that RTCD would always
 104 //     go to a new page, but that is not guaranteed; skip ucache.
 105 //   rRALR. Since it is before a segment change, the ucache will always miss.
 106 //   Ring brackets.  They will be the same, so recheck is unnecessary.
 107 //   ACVs: They will be the same, so recheck is unnecessary.
 108 //   SDW/PTW : They will be the same, so recheck is unnecessary.
 109 //   Prepage mode:  Skip ucache.
 110 //   History registers... Hm. skip for now; Values could be stashed...
 111 
 112 // Is this cycle a candidate for ucache?
 113 
 114 //#define TEST_UCACHE
 115 #if defined(TEST_UCACHE)
 116   bool cacheHit;
 117   cacheHit = false; // Assume skip...
 118 #endif
 119 
 120   // lastCycle == RTCD_OPERAND_FETCH
 121   if (i->opcode == 0610  && ! i->opcodeX) {
 122     //sim_printf ("skip RTCD\r\n");
 123     goto skip_ucache;
 124   }
 125 
 126   // RALR
 127   if (cpu.rRALR) {
 128     //sim_printf ("skip rRALR\r\n");
 129     goto skip_ucache;
 130   }
 131 
 132   // Prepage mode?
 133   // check for "uninterruptible" EIS instruction
 134   // ISOLTS-878 02: mvn,cmpn,mvne,ad3d; obviously also
 135   // ad2/3d,sb2/3d,mp2/3d,dv2/3d
 136   // DH03 p.8-13: probably also mve,btd,dtb
 137   if (i->opcodeX && ((i->opcode & 0770)== 0200|| (i->opcode & 0770) == 0220
 138       || (i->opcode & 0770)== 020|| (i->opcode & 0770) == 0300)) {
 139     //sim_printf ("skip uninterruptible\r\n");
 140     goto skip_ucache;
 141   }
 142 
 143 // Yes; check the ucache
 144 
 145 //#define TEST_UCACHE
 146 #if defined(TEST_UCACHE)
 147   word24 cachedAddress;
 148   word3 cachedR1;
 149   word14 cachedBound;
 150   word1 cachedP;
 151   bool cachedPaged;
 152   cacheHit =
 153       ucCacheCheck (cpup, this, cpu.TPR.TSR, cpu.TPR.CA, & cachedBound, & cachedP, & cachedAddress, & cachedR1, & cachedPaged);
 154   goto miss_ucache;
 155 #else
 156   if (! ucCacheCheck (cpup, this, cpu.TPR.TSR, cpu.TPR.CA, & bound, & p, & pageAddress, & RSDWH_R1, & paged))
 157     goto miss_ucache;
 158 #endif
 159 
 160   if (paged) {
 161     finalAddress = pageAddress + (cpu.TPR.CA & OS18MASK);
 162   } else {
 163     finalAddress = pageAddress + cpu.TPR.CA;
 164   }
 165   cpu.RSDWH_R1 = RSDWH_R1;
 166 
 167 // ucache hit; housekeeping...
 168   //sim_printf ("hit  %d %05o:%06o\r\n", evcnt, cpu.TPR.TSR, cpu.TPR.CA);
 169 
 170   // the APU status of the cycle, as the miss path sets it (PA865 03A)
 171   set_apu_status (cpup, paged ? apuStatus_FAP : apuStatus_FANP);
 172   L68_PI_AP;
 173   cpu.apu.lastCycle = INSTRUCTION_FETCH;
 174   goto HI;
 175 
 176 skip_ucache:;
 177   //sim_printf ("miss %d %05o:%06o\r\n", evcnt, cpu.TPR.TSR, cpu.TPR.CA);
 178 #if defined(UCACHE_STATS)
 179   cpu.uCache.skips[this] ++;
 180 #endif
 181 
 182 miss_ucache:;
 183 
 184   bool nomatch = true;
 185   if (cpu.tweaks.enable_wam) {
 186     // AL39: The associative memory is ignored (forced to "no match") during
 187     // address preparation.
 188     // lptp,lptr,lsdp,lsdr,sptp,sptr,ssdp,ssdr
 189     // Unfortunately, ISOLTS doesn't try to execute any of these in append mode.
 190     // XXX should this be only for OPERAND_READ and OPERAND_STORE?
 191     nomatch = ((i->opcode == 0232 || i->opcode == 0254 ||
 192                 i->opcode == 0154 || i->opcode == 0173) &&
 193                 i->opcodeX ) ||
 194                ((i->opcode == 0557 || i->opcode == 0257) &&
 195                 ! i->opcodeX);
 196   }
 197 
 198   processor_cycle_type lastCycle = cpu.apu.lastCycle;
 199   cpu.apu.lastCycle = INSTRUCTION_FETCH;
 200 
 201   DBGAPP ("doAppendCycleInstructionFetch(Entry) XSF %o\r\n", cpu.cu.XSF);
 202 
 203   PNL (L68_ (cpu.apu.state = 0;))
 204 
 205   cpu.RSDWH_R1 = 0;
 206 
 207   cpu.acvFaults = 0;
 208 
 209 //#define FMSG(x) x
 210 #define FMSG(x)
 211   FMSG (char * acvFaultsMsg = "<unknown>";)
 212 
 213 ////////////////////////////////////////
 214 //
 215 // Sheet 2: "A"
 216 //
 217 ////////////////////////////////////////
 218 
 219 //
 220 //  A:
 221 //    Get SDW
 222 
 223   //PNL (cpu.APUMemAddr = address;)
 224   PNL (cpu.APUMemAddr = cpu.TPR.CA;)
 225 
 226   DBGAPP ("doAppendCycleInstructionFetch(A)\r\n");
 227 
 228   // is SDW for C(TPR.TSR) in SDWAM?
 229   if (nomatch || ! fetch_sdw_from_sdwam (cpup, cpu.TPR.TSR)) {
 230     // No
 231     DBGAPP ("doAppendCycleInstructionFetch(A):SDW for segment %05o not in SDWAM\r\n", cpu.TPR.TSR);
 232 
 233     DBGAPP ("doAppendCycleInstructionFetch(A):DSBR.U=%o\r\n", cpu.DSBR.U);
 234 
 235     if (cpu.DSBR.U == 0) {
 236       fetch_dsptw (cpup, cpu.TPR.TSR);
 237 
 238       if (! cpu.PTW0.DF)
 239         doFault (FAULT_DF0 + cpu.PTW0.FC, fst_zero, "doAppendCycleInstructionFetch(A): PTW0.F == 0");
 240 
 241       if (! cpu.PTW0.U)
 242         modify_dsptw (cpup, cpu.TPR.TSR);
 243 
 244       fetch_psdw (cpup, cpu.TPR.TSR);
 245     } else
 246       fetch_nsdw (cpup, cpu.TPR.TSR); // load SDW0 from descriptor segment table.
 247 
 248     if (cpu.SDW0.DF == 0) {
 249       DBGAPP ("doAppendCycleInstructionFetch(A): SDW0.F == 0! " "Initiating directed fault\r\n");
 250       // initiate a directed fault ...
 251       doFault (FAULT_DF0 + cpu.SDW0.FC, fst_zero, "SDW0.F == 0");
 252     }
 253     // load SDWAM .....
 254     load_sdwam (cpup, cpu.TPR.TSR, nomatch);
 255   }
 256   DBGAPP ("doAppendCycleInstructionFetch(A) R1 %o R2 %o R3 %o E %o\r\n", cpu.SDW->R1, cpu.SDW->R2, cpu.SDW->R3, cpu.SDW->E);
 257 
 258   // Yes...
 259   RSDWH_R1 = cpu.RSDWH_R1 = cpu.SDW->R1;
 260 
 261 ////////////////////////////////////////
 262 //
 263 // Sheet 3: "B"
 264 //
 265 ////////////////////////////////////////
 266 
 267 //
 268 // B: Check the ring
 269 //
 270 
 271   DBGAPP ("doAppendCycleInstructionFetch(B)\r\n");
 272 
 273   // check ring bracket consistency
 274 
 275   //C(SDW.R1) <= C(SDW.R2) <= C(SDW .R3)?
 276   if (! (cpu.SDW->R1 <= cpu.SDW->R2 && cpu.SDW->R2 <= cpu.SDW->R3)) {
 277     // Set fault ACV0 = IRO
 278     cpu.acvFaults |= ACV0;
 279     PNL (L68_ (cpu.apu.state |= apu_FLT;))
 280     FMSG (acvFaultsMsg = "acvFaults(B) C(SDW.R1) <= C(SDW.R2) <= " "C(SDW .R3)";)
 281   }
 282 
 283   // lastCycle == RTCD_OPERAND_FETCH
 284   // if a fault happens between the RTCD_OPERAND_FETCH and the INSTRUCTION_FETCH
 285   // of the next instruction - this happens about 35 time for just booting  and
 286   // shutting down multics -- a stored lastCycle is useless.
 287   // the opcode is preserved across faults and only replaced as the
 288   // INSTRUCTION_FETCH succeeds.
 289   if (i->opcode == 0610  && ! i->opcodeX)
 290     goto C;
 291 
 292   if (lastCycle == RTCD_OPERAND_FETCH)
 293     sim_warn ("%s: lastCycle == RTCD_OPERAND_FETCH opcode %0#o\r\n", __func__, i->opcode);
 294 
 295   //
 296   // B1: The operand is one of: an instruction, data to be read or data to be
 297   //     written
 298   //
 299 
 300   // Transfer or instruction fetch?
 301   goto F;
 302 
 303 ////////////////////////////////////////
 304 //
 305 // Sheet 4: "C" "D"
 306 //
 307 ////////////////////////////////////////
 308 
 309 C:;
 310   DBGAPP ("doAppendCycleInstructionFetch(C)\r\n");
 311 
 312   //
 313   // check ring bracket for instruction fetch after rtcd instruction
 314   //
 315   //   allow outbound transfers (cpu.TPR.TRR >= cpu.PPR.PRR)
 316   //
 317 
 318   // C(TPR.TRR) < C(SDW.R1)?
 319   // C(TPR.TRR) > C(SDW.R2)?
 320   if (cpu.TPR.TRR < cpu.SDW->R1 || cpu.TPR.TRR > cpu.SDW->R2) {
 321     DBGAPP ("ACV1 c\r\n");
 322     DBGAPP ("acvFaults(C) ACV1 ! ( C(SDW .R1) %o <= C(TPR.TRR) %o <= C(SDW .R2) %o )\r\n", cpu.SDW->R1, cpu.TPR.TRR, cpu.SDW->R2);
 323     //Set fault ACV1 = OEB
 324     cpu.acvFaults |= ACV1;
 325     PNL (L68_ (cpu.apu.state |= apu_FLT;))
 326     FMSG (acvFaultsMsg = "acvFaults(C) C(SDW.R1 > C(TPR.TRR) > C(SDW.R2)";)
 327   }
 328   // SDW.E set ON?
 329   if (! cpu.SDW->E) {
 330     DBGAPP ("ACV2 a\r\n");
 331     DBGAPP ("doAppendCycleInstructionFetch(C) ACV2\r\n");
 332     //Set fault ACV2 = E-OFF
 333     cpu.acvFaults |= ACV2;
 334     PNL (L68_ (cpu.apu.state |= apu_FLT;))
 335     FMSG (acvFaultsMsg = "acvFaults(C) SDW.E";)
 336   }
 337   if (cpu.TPR.TRR > cpu.PPR.PRR)
 338     sim_warn ("rtcd: outbound call cpu.TPR.TRR %d cpu.PPR.PRR %d\r\n", cpu.TPR.TRR, cpu.PPR.PRR);
 339   // C(TPR.TRR) >= C(PPR.PRR)
 340   if (cpu.TPR.TRR < cpu.PPR.PRR) {
 341     DBGAPP ("ACV11\r\n");
 342     DBGAPP ("doAppendCycleInstructionFetch(C) ACV11\r\n");
 343     //Set fault ACV11 = INRET
 344     cpu.acvFaults |= ACV11;
 345     PNL (L68_ (cpu.apu.state |= apu_FLT;))
 346     FMSG (acvFaultsMsg = "acvFaults(C) TRR>=PRR";)
 347   }
 348 
 349 D:;
 350   DBGAPP ("doAppendCycleInstructionFetch(D)\r\n");
 351 
 352   // transfer or instruction fetch
 353 
 354   // check ring alarm to catch outbound transfers
 355 
 356   if (cpu.rRALR == 0)
 357     goto G;
 358 
 359   // C(PPR.PRR) < RALR?
 360   if (! (cpu.PPR.PRR < cpu.rRALR)) {
 361     DBGAPP ("ACV13\r\n");
 362     DBGAPP ("acvFaults(D) C(PPR.PRR) %o < RALR %o\r\n", cpu.PPR.PRR, cpu.rRALR);
 363     cpu.acvFaults |= ACV13;
 364     PNL (L68_ (cpu.apu.state |= apu_FLT;))
 365     FMSG (acvFaultsMsg = "acvFaults(D) C(PPR.PRR) < RALR";)
 366   }
 367 
 368   goto G;
 369 
 370 ////////////////////////////////////////
 371 //
 372 // Sheet 6: "F"
 373 //
 374 ////////////////////////////////////////
 375 
 376 F:;
 377   PNL (L68_ (cpu.apu.state |= apu_PIAU;))
 378   DBGAPP ("doAppendCycleInstructionFetch(F): transfer or instruction fetch\r\n");
 379 
 380   //
 381   // check ring bracket for instruction fetch
 382   //
 383 
 384   // C(TPR.TRR) > C(SDW .R2)?
 385   if (cpu.TPR.TRR < cpu.SDW->R1 || cpu.TPR.TRR > cpu.SDW->R2) {
 386     DBGAPP ("ACV1 a/b\r\n");
 387     DBGAPP ("acvFaults(F) ACV1 !( C(SDW .R1) %o <= C(TPR.TRR) %o <= C(SDW .R2) %o )\r\n", cpu.SDW->R1, cpu.TPR.TRR, cpu.SDW->R2);
 388     cpu.acvFaults |= ACV1;
 389     PNL (L68_ (cpu.apu.state |= apu_FLT;))
 390     FMSG (acvFaultsMsg = "acvFaults(F) C(TPR.TRR) < C(SDW .R1)";)
 391   }
 392   // SDW .E set ON?
 393   if (! cpu.SDW->E) {
 394     DBGAPP ("ACV2 c\r\n");
 395     DBGAPP ("doAppendCycleInstructionFetch(F) ACV2\r\n");
 396     cpu.acvFaults |= ACV2;
 397     PNL (L68_ (cpu.apu.state |= apu_FLT;))
 398     FMSG (acvFaultsMsg = "acvFaults(F) SDW .E set OFF";)
 399   }
 400 
 401   // C(PPR.PRR) = C(TPR.TRR)?
 402   if (cpu.PPR.PRR != cpu.TPR.TRR) {
 403     DBGAPP ("ACV12\r\n");
 404     DBGAPP ("doAppendCycleInstructionFetch(F) ACV12\r\n");
 405     //Set fault ACV12 = CRT
 406     cpu.acvFaults |= ACV12;
 407     PNL (L68_ (cpu.apu.state |= apu_FLT;))
 408     FMSG (acvFaultsMsg = "acvFaults(F) C(PPR.PRR) != C(TPR.TRR)";)
 409   }
 410 
 411   goto D;
 412 
 413 ////////////////////////////////////////
 414 //
 415 // Sheet 7: "G"
 416 //
 417 ////////////////////////////////////////
 418 
 419 G:;
 420 
 421   DBGAPP ("doAppendCycleInstructionFetch(G)\r\n");
 422 
 423   //C(TPR.CA)0,13 > SDW.BOUND?
 424   if (((cpu.TPR.CA >> 4) & 037777) > cpu.SDW->BOUND) {
 425     DBGAPP ("ACV15\r\n");
 426     DBGAPP ("doAppendCycleInstructionFetch(G) ACV15\r\n");
 427     cpu.acvFaults |= ACV15;
 428     PNL (L68_ (cpu.apu.state |= apu_FLT;))
 429     FMSG (acvFaultsMsg = "acvFaults(G) C(TPR.CA)0,13 > SDW.BOUND";)
 430     DBGAPP ("acvFaults(G) C(TPR.CA)0,13 > SDW.BOUND\r\n" "   CA %06o CA>>4 & 037777 %06o SDW->BOUND %06o",
 431             cpu.TPR.CA, ((cpu.TPR.CA >> 4) & 037777), cpu.SDW->BOUND);
 432   }
 433   bound = cpu.SDW->BOUND;
 434   p = cpu.SDW->P;
 435 
 436   if (cpu.acvFaults) {
 437     DBGAPP ("doAppendCycleInstructionFetch(G) acvFaults\r\n");
 438     PNL (L68_ (cpu.apu.state |= apu_FLT;))
 439     // Initiate an access violation fault
 440     doFault (FAULT_ACV, (_fault_subtype) {.fault_acv_subtype=cpu.acvFaults}, "ACV fault");
 441   }
 442 
 443   // is segment C(TPR.TSR) paged?
 444   if (cpu.SDW->U)
 445     goto H; // Not paged
 446 
 447   // Yes. segment is paged ...
 448   // is PTW for C(TPR.CA) in PTWAM?
 449 
 450   DBGAPP ("doAppendCycleInstructionFetch(G) CA %06o\r\n", cpu.TPR.CA);
 451   if (nomatch ||
 452       ! fetch_ptw_from_ptwam (cpup, cpu.SDW->POINTER, cpu.TPR.CA)) {
 453     fetch_ptw (cpup, cpu.SDW, cpu.TPR.CA);
 454     if (! cpu.PTW0.DF) {
 455       // initiate a directed fault
 456       doFault (FAULT_DF0 + cpu.PTW0.FC, (_fault_subtype) {.bits=0}, "PTW0.F == 0");
 457     }
 458     loadPTWAM (cpup, cpu.SDW->POINTER, cpu.TPR.CA, nomatch); // load PTW0 to PTWAM
 459   }
 460 
 461   // Prepage mode?
 462   // check for "uninterruptible" EIS instruction
 463   // ISOLTS-878 02: mvn,cmpn,mvne,ad3d; obviously also
 464   // ad2/3d,sb2/3d,mp2/3d,dv2/3d
 465   // DH03 p.8-13: probably also mve,btd,dtb
 466 
 467   // XXX: PVS-Studio says that "i->opcodeX" is ALWAYS FALSE in the following check:
 468   if (i->opcodeX && ((i->opcode & 0770)== 0200|| (i->opcode & 0770) == 0220 //-V560
 469       || (i->opcode & 0770)== 020|| (i->opcode & 0770) == 0300)) {
 470       do_ptw2 (cpup, cpu.SDW, cpu.TPR.CA);
 471     }
 472   goto I;
 473 
 474 ////////////////////////////////////////
 475 //
 476 // Sheet 8: "H", "I"
 477 //
 478 ////////////////////////////////////////
 479 
 480 H:;
 481   DBGAPP ("doAppendCycleInstructionFetch(H): FANP\r\n");
 482 
 483   paged = false;
 484 
 485   PNL (L68_ (cpu.apu.state |= apu_FANP;))
 486 
 487 
 488 
 489 
 490 
 491 
 492 
 493 
 494   set_apu_status (cpup, apuStatus_FANP);
 495   L68_PI_AP;
 496 
 497   DBGAPP ("doAppendCycleInstructionFetch(H): SDW->ADDR=%08o CA=%06o\r\n", cpu.SDW->ADDR, cpu.TPR.CA);
 498 
 499   pageAddress = (cpu.SDW->ADDR & 077777760);
 500   finalAddress = (cpu.SDW->ADDR & 077777760) + cpu.TPR.CA;
 501   finalAddress &= 0xffffff;
 502   PNL (cpu.APUMemAddr = finalAddress;)
 503 
 504   DBGAPP ("doAppendCycleInstructionFetch(H:FANP): (%05o:%06o) finalAddress=%08o\r\n", cpu.TPR.TSR, cpu.TPR.CA, finalAddress);
 505 
 506   goto HI;
 507 
 508 I:;
 509 
 510 // Set PTW.M
 511 
 512   DBGAPP ("doAppendCycleInstructionFetch(I): FAP\r\n");
 513 
 514   paged = true;
 515 
 516   // final address paged
 517   set_apu_status (cpup, apuStatus_FAP);
 518   L68_PI_AP;
 519   PNL (L68_ (cpu.apu.state |= apu_FAP;))
 520 
 521   word24 y2 = cpu.TPR.CA % 1024;
 522 
 523   pageAddress = (((word24)cpu.PTW->ADDR & 0777760) << 6);
 524   // AL39: The hardware ignores low order bits of the main memory page
 525   // address according to page size
 526   finalAddress = (((word24)cpu.PTW->ADDR & 0777760) << 6) + y2;
 527   finalAddress &= 0xffffff;
 528   PNL (cpu.APUMemAddr = finalAddress;)
 529 
 530   L68_ (
 531     if (cpu.MR_cache.emr && cpu.MR_cache.ihr)
 532       add_l68_APU_history (cpup, APUH_FAP);
 533   )
 534 
 535   DBGAPP ("doAppendCycleInstructionFetch(H:FAP): (%05o:%06o) finalAddress=%08o\r\n", cpu.TPR.TSR, cpu.TPR.CA, finalAddress);
 536 
 537 HI:
 538   DBGAPP ("doAppendCycleInstructionFetch(HI)\r\n");
 539 
 540 #if defined(TEST_UCACHE)
 541   if (cacheHit) {
 542     bool err = false;
 543     if (cachedAddress != pageAddress) {
 544      sim_printf ("cachedAddress %08o != pageAddress %08o\r\n", cachedAddress, pageAddress);
 545      err = true;
 546     }
 547     if (cachedR1 != RSDWH_R1) {
 548       sim_printf ("cachedR1 %01o != RSDWH_R1 %01o\r\n", cachedR1, RSDWH_R1);
 549       err = true;
 550     }
 551     if (cachedBound != bound) {
 552       sim_printf ("cachedBound %01o != bound %01o\r\n", cachedBound, bound);
 553       err = true;
 554     }
 555     if (cachedPaged != paged) {
 556       sim_printf ("cachedPaged %01o != paged %01o\r\n", cachedPaged, paged);
 557       err = true;
 558     }
 559     if (err) {
 560 # if defined(HDBG)
 561       HDBGPrint ();
 562 # endif
 563       sim_printf ("ins fetch err  %d %05o:%06o\r\n", evcnt, cpu.TPR.TSR, cpu.TPR.CA);
 564       exit (1);
 565     }
 566     //sim_printf ("hit  %d %05o:%06o\r\n", evcnt, cpu.TPR.TSR, cpu.TPR.CA);
 567 # if defined(HDBG)
 568     hdbgNote ("doAppendCycleOperandRead.h", "test hit %d %05o:%06o\r\n", evcnt, cpu.TPR.TSR, cpu.TPR.CA);
 569 # endif
 570   } else {
 571     //sim_printf ("miss %d %05o:%06o\r\n", evcnt, cpu.TPR.TSR, cpu.TPR.CA);
 572 # if defined(HDBG)
 573     hdbgNote ("doAppendCycleOperandRead.h", "test miss %d %05o:%06o\r\n", evcnt, cpu.TPR.TSR, cpu.TPR.CA);
 574 # endif
 575   }
 576 #endif
 577 #if defined(TEST_UCACHE)
 578 if (cacheHit) {
 579   if (cachedPaged != paged) sim_printf ("cachedPaged %01o != paged %01o\r\n", cachedPaged, paged);
 580   //sim_printf ("hit  %d %05o:%06o\r\n", evcnt, cpu.TPR.TSR, cpu.TPR.CA);
 581 }
 582 else
 583 {
 584   //sim_printf ("miss %d %05o:%06o\r\n", evcnt, cpu.TPR.TSR, cpu.TPR.CA);
 585 }
 586 #endif
 587 
 588   ucCacheSave (cpup, this, cpu.TPR.TSR, cpu.TPR.CA, bound, p, pageAddress, RSDWH_R1, paged);
 589 evcnt ++;
 590   // isolts 870
 591   cpu.cu.XSF = 1;
 592   sim_debug (DBG_TRACEEXT, & cpu_dev, "loading of cpu.TPR.TSR sets XSF to 1\r\n");
 593 
 594   core_readN (cpup, finalAddress, data, nWords, "INSTRUCTION_FETCH");
 595 
 596 ////////////////////////////////////////
 597 //
 598 // Sheet 10: "K", "L", "M", "N"
 599 //
 600 ////////////////////////////////////////
 601 
 602 //L:; // Transfer or instruction fetch
 603 
 604   DBGAPP ("doAppendCycleInstructionFetch(L)\r\n");
 605 
 606   // lastCycle == RTCD_OPERAND_FETCH
 607 
 608   if (i->opcode == 0610  && ! i->opcodeX) {
 609     // C(PPR.PRR) -> C(PRn.RNR) for n = (0, 1, ..., 7)
 610     // Use TRR here; PRR not set until KL
 611     CPTUR (cptUsePRn + 0);
 612     CPTUR (cptUsePRn + 1);
 613     CPTUR (cptUsePRn + 2);
 614     CPTUR (cptUsePRn + 3);
 615     CPTUR (cptUsePRn + 4);
 616     CPTUR (cptUsePRn + 5);
 617     CPTUR (cptUsePRn + 6);
 618     CPTUR (cptUsePRn + 7);
 619     cpu.PR[0].RNR =
 620     cpu.PR[1].RNR =
 621     cpu.PR[2].RNR =
 622     cpu.PR[3].RNR =
 623     cpu.PR[4].RNR =
 624     cpu.PR[5].RNR =
 625     cpu.PR[6].RNR =
 626     cpu.PR[7].RNR = cpu.TPR.TRR;
 627 #if defined(TESTING)
 628     HDBGRegPRW (0, "app rtcd");
 629     HDBGRegPRW (1, "app rtcd");
 630     HDBGRegPRW (2, "app rtcd");
 631     HDBGRegPRW (3, "app rtcd");
 632     HDBGRegPRW (4, "app rtcd");
 633     HDBGRegPRW (5, "app rtcd");
 634     HDBGRegPRW (6, "app rtcd");
 635     HDBGRegPRW (7, "app rtcd");
 636 #endif
 637   }
 638   goto KL;
 639 
 640 KL:
 641   DBGAPP ("doAppendCycleInstructionFetch(KL)\r\n");
 642 
 643   // C(TPR.TSR) -> C(PPR.PSR)
 644   cpu.PPR.PSR = cpu.TPR.TSR;
 645   // C(TPR.CA) -> C(PPR.IC)
 646   cpu.PPR.IC = cpu.TPR.CA;
 647 
 648   goto M;
 649 
 650 M: // Set P
 651   DBGAPP ("doAppendCycleInstructionFetch(M)\r\n");
 652 
 653   // C(TPR.TRR) = 0?
 654   if (cpu.TPR.TRR == 0) {
 655     // C(SDW.P) -> C(PPR.P)
 656     //cpu.PPR.P = cpu.SDW->P;
 657     cpu.PPR.P = p;
 658   } else {
 659     // 0 C(PPR.P)
 660     cpu.PPR.P = 0;
 661   }
 662 
 663   PNL (cpu.APUDataBusOffset = cpu.TPR.CA;)
 664   PNL (cpu.APUDataBusAddr = finalAddress;)
 665 
 666   PNL (L68_ (cpu.apu.state |= apu_FA;))
 667 
 668   DBGAPP ("doAppendCycleInstructionFetch (Exit) PRR %o PSR %05o P %o IC %06o\r\n",
 669           cpu.PPR.PRR, cpu.PPR.PSR, cpu.PPR.P, cpu.PPR.IC);
 670   DBGAPP ("doAppendCycleInstructionFetch (Exit) TRR %o TSR %05o TBR %02o CA %06o\r\n",
 671           cpu.TPR.TRR, cpu.TPR.TSR, cpu.TPR.TBR, cpu.TPR.CA);
 672 
 673   return finalAddress;
 674 }
 675 #undef TEST_UCACHE

/* [previous][next][first][last][top][bottom][index][help] */