root/src/dps8/doAppendCycleOperandRead.h

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

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. doAppendCycleOperandRead

   1 /*
   2  * vim: filetype=c:tabstop=4:ai:expandtab
   3  * SPDX-License-Identifier: ICU
   4  * scspell-id: 3b4b8be2-171d-11ee-84fd-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 //
  19 //        A:   fetch sdw
  20 //        B:   check RB consistency
  21 //        B1:  Is CALL6? Yes---------------------------------------+
  22 //               No                                                |
  23 //             Is transfer? Yes---------------+                E: Check RB
  24 //               No                           |                    |
  25 //             Check Read RB             F: Check Execute RB       |
  26 //                |                      D: Check RALR             |
  27 //                |                           |                    |
  28 //                +<--------------------------+<-------------------+
  29 //                |
  30 //                V
  31 //        G:   Check bound
  32 //             Paged? No----------------------+
  33 //               Yes                          |
  34 //             Fetch PTW                      |
  35 //        I:   Compute final address     H:   Compute Final Address
  36 //                |                           |
  37 //                +<--------------------------+
  38 //                |
  39 //                V
  40 //        HI:  Read operand
  41 //             CALL6? Yes--------------------------------------+
  42 //               No                                            |
  43 //             Transfer? Yes -----------------+                |
  44 //               No                           |                |
  45 //                |                           |                |
  46 //                |                      L:  Handle TSPn   N: Handle CALL6
  47 //                |                      KL: Set IC           Set IC
  48 //                |                           |                |
  49 //                |                           +<---------------+
  50 //                |                           |
  51 //                |                      M: Set P
  52 //                |                           |
  53 //                +<--------------------------+
  54 //                |
  55 //                V
  56 //              Exit
  57 
  58 word24 doAppendCycleOperandRead (cpu_state_t * cpup, word36 * data, uint nWords) {
     /* [previous][next][first][last][top][bottom][index][help] */
  59 static int evcnt = 0;
  60   DCDstruct * i = & cpu.currentInstruction;
  61   (void)evcnt;
  62   DBGAPP ("doAppendCycleOperandRead(Entry) thisCycle=OPERAND_READ\r\n");
  63   DBGAPP ("doAppendCycleOperandRead(Entry) lastCycle=%s\r\n", str_pct (cpu.apu.lastCycle));
  64   DBGAPP ("doAppendCycleOperandRead(Entry) CA %06o\r\n", cpu.TPR.CA);
  65   DBGAPP ("doAppendCycleOperandRead(Entry) n=%2u\r\n", nWords);
  66   DBGAPP ("doAppendCycleOperandRead(Entry) PPR.PRR=%o PPR.PSR=%05o\r\n", cpu.PPR.PRR, cpu.PPR.PSR);
  67   DBGAPP ("doAppendCycleOperandRead(Entry) TPR.TRR=%o TPR.TSR=%05o\r\n", cpu.TPR.TRR, cpu.TPR.TSR);
  68 
  69   if (i->b29) {
  70     DBGAPP ("doAppendCycleOperandRead(Entry) isb29 PRNO %o\r\n", GET_PRN (IWB_IRODD));
  71   }
  72 
  73   uint this = UC_OPERAND_READ;
  74   if (i->info->flags & TRANSFER_INS)
  75     this = UC_OPERAND_READ_TRA;
  76   if (i->info->flags & CALL6_INS)
  77     this = UC_OPERAND_READ_CALL6;
  78 
  79   word24 finalAddress = 0;
  80   word24 pageAddress = 0;
  81   word3 RSDWH_R1 = 0;
  82   word14 bound = 0;
  83   word1 p = 0;
  84   bool paged;
  85 
  86 // Is this cycle a candidate for ucache?
  87 
  88 //#define TEST_UCACHE
  89 #if defined(TEST_UCACHE)
  90   bool cacheHit;
  91   cacheHit = false; // Assume skip...
  92 #endif /* if defined(TEST_UCACHE) */
  93 
  94 
  95   // Is OPCODE call6?
  96 
  97   // See E1; The TRR needs to be checked and set to R2; this will vary across different
  98   // CALL6 calls.
  99   if (i->info->flags & CALL6_INS) {
 100 # if defined(UCACHE_STATS)
 101     cpu.uCache.call6Skips ++;
 102 # endif /* if defined(UCACHE_STATS) */
 103     goto skip;
 104   }
 105 
 106 
 107 
 108 
 109 
 110 
 111 
 112 
 113 
 114 
 115   // Transfer?
 116   if (i->info->flags & TRANSFER_INS) {
 117     // check ring alarm to catch outbound transfers
 118     if (cpu.rRALR && (cpu.PPR.PRR >= cpu.rRALR)) {
 119 #if defined(UCACHE_STATS)
 120       cpu.uCache.ralrSkips ++;
 121 #endif /* if defined(UCACHE_STATS) */
 122       goto skip;
 123     }
 124   }
 125 
 126 // Yes; check the ucache
 127 
 128 #if defined(TEST_UCACHE)
 129   word24 cachedAddress;
 130   word3 cachedR1;
 131   word14 cachedBound;
 132   word1 cachedP;
 133   bool cachedPaged;
 134   cacheHit =
 135       ucCacheCheck (cpup, this, cpu.TPR.TSR, cpu.TPR.CA, & cachedBound, & cachedP, & cachedAddress, & cachedR1, & cachedPaged);
 136 # if defined(HDBG)
 137   hdbgNote ("doAppendCycleOperandRead.h", "test cache check %s %d %u %05o:%06o %05o %o %08o %o %o",
 138             cacheHit ? "hit" : "miss", evcnt, this, cpu.TPR.TSR, cpu.TPR.CA, cachedBound,
 139             cachedP, cachedAddress, cachedR1, cachedPaged);
 140 # endif /* if defined(HDBG) */
 141   goto miss;
 142 #else
 143   if (! ucCacheCheck (cpup, this, cpu.TPR.TSR, cpu.TPR.CA, & bound, & p, & pageAddress, & RSDWH_R1, & paged)) {
 144 # if defined(HDBG)
 145     hdbgNote ("doAppendCycleOperandRead.h", "miss %d %05o:%06o\r\n", evcnt, cpu.TPR.TSR, cpu.TPR.CA);
 146 # endif /* if defined(HDBG) */
 147     goto miss;
 148   }
 149 #endif /* if defined(TEST_UCACHE) */
 150 
 151   if (paged) {
 152     finalAddress = pageAddress + (cpu.TPR.CA & OS18MASK);
 153   } else {
 154     finalAddress = pageAddress + cpu.TPR.CA;
 155   }
 156   cpu.RSDWH_R1 = RSDWH_R1;
 157 
 158 // ucache hit; housekeeping...
 159   //sim_printf ("hit  %d %05o:%06o\r\n", evcnt, cpu.TPR.TSR, cpu.TPR.CA);
 160 #if defined(HDBG)
 161   hdbgNote ("doAppendCycleOperandRead.h", "hit  %d %05o:%06o\r\n", evcnt, cpu.TPR.TSR, cpu.TPR.CA);
 162 #endif /* if defined(HDBG) */
 163 
 164   // the APU status of the cycle, as the miss path sets it (PA865 03A)
 165   set_apu_status (cpup, paged ? apuStatus_FAP : apuStatus_FANP);
 166   cpu.apu.lastCycle = OPERAND_READ;
 167   goto HI;
 168 
 169 
 170 skip:;
 171   //sim_printf ("miss %d %05o:%06o\r\n", evcnt, cpu.TPR.TSR, cpu.TPR.CA);
 172 # if defined(HDBG)
 173   hdbgNote ("doAppendCycleOperandRead.h", "skip %d %05o:%06o\r\n", evcnt, cpu.TPR.TSR, cpu.TPR.CA);
 174 # endif /* if defined(HDBG) */
 175 # if defined(UCACHE_STATS)
 176   cpu.uCache.skips[this] ++;
 177 # endif /* if defined(UCACHE_STATS) */
 178 
 179 
 180 miss:;
 181 
 182   bool nomatch = true;
 183   if (cpu.tweaks.enable_wam) {
 184     // AL39: The associative memory is ignored (forced to "no match") during
 185     // address preparation.
 186     // lptp,lptr,lsdp,lsdr,sptp,sptr,ssdp,ssdr
 187     // Unfortunately, ISOLTS doesn't try to execute any of these in append mode.
 188     // XXX should this be only for OPERAND_READ and OPERAND_STORE?
 189     nomatch = ((i->opcode == 0232 || i->opcode == 0254 ||
 190                 i->opcode == 0154 || i->opcode == 0173) &&
 191                 i->opcodeX ) ||
 192                ((i->opcode == 0557 || i->opcode == 0257) &&
 193                 ! i->opcodeX);
 194   }
 195 
 196   processor_cycle_type lastCycle = cpu.apu.lastCycle;
 197   cpu.apu.lastCycle = OPERAND_READ;
 198 
 199   DBGAPP ("doAppendCycleOperandRead(Entry) XSF %o\r\n", cpu.cu.XSF);
 200 
 201   PNL (L68_ (cpu.apu.state = 0;))
 202 
 203   cpu.RSDWH_R1 = 0;
 204 
 205   cpu.acvFaults = 0;
 206 
 207 //#define FMSG(x) x
 208 #define FMSG(x)
 209   FMSG (char * acvFaultsMsg = "<unknown>";)
 210 
 211 ////////////////////////////////////////
 212 //
 213 // Sheet 1: "START APPEND"
 214 //
 215 ////////////////////////////////////////
 216 
 217 // START APPEND
 218   word3 n = 0; // PRn to be saved to TSN_PRNO
 219 
 220 ////////////////////////////////////////
 221 //
 222 // Sheet 2: "A"
 223 //
 224 ////////////////////////////////////////
 225 
 226 //
 227 //  A:
 228 //    Get SDW
 229 
 230   //PNL (cpu.APUMemAddr = address;)
 231   PNL (cpu.APUMemAddr = cpu.TPR.CA;)
 232 
 233   DBGAPP ("doAppendCycleOperandRead(A)\r\n");
 234 
 235   // is SDW for C(TPR.TSR) in SDWAM?
 236   if (nomatch || ! fetch_sdw_from_sdwam (cpup, cpu.TPR.TSR)) {
 237     // No
 238     DBGAPP ("doAppendCycleOperandRead(A):SDW for segment %05o not in SDWAM\r\n", cpu.TPR.TSR);
 239     DBGAPP ("doAppendCycleOperandRead(A):DSBR.U=%o\r\n", cpu.DSBR.U);
 240 
 241     if (cpu.DSBR.U == 0) {
 242       fetch_dsptw (cpup, cpu.TPR.TSR);
 243 
 244       if (! cpu.PTW0.DF)
 245         doFault (FAULT_DF0 + cpu.PTW0.FC, fst_zero, "doAppendCycleOperandRead(A): PTW0.F == 0");
 246 
 247       if (! cpu.PTW0.U)
 248         modify_dsptw (cpup, cpu.TPR.TSR);
 249 
 250       fetch_psdw (cpup, cpu.TPR.TSR);
 251     } else
 252       fetch_nsdw (cpup, cpu.TPR.TSR); // load SDW0 from descriptor segment table.
 253 
 254     if (cpu.SDW0.DF == 0) {
 255       DBGAPP ("doAppendCycleOperandRead(A): SDW0.F == 0! " "Initiating directed fault\r\n");
 256       // initiate a directed fault ...
 257       doFault (FAULT_DF0 + cpu.SDW0.FC, fst_zero, "SDW0.F == 0");
 258     }
 259     // load SDWAM .....
 260     load_sdwam (cpup, cpu.TPR.TSR, nomatch);
 261   }
 262   DBGAPP ("doAppendCycleOperandRead(A) R1 %o R2 %o R3 %o E %o\r\n", cpu.SDW->R1, cpu.SDW->R2, cpu.SDW->R3, cpu.SDW->E);
 263 
 264   // Yes...
 265   RSDWH_R1 = cpu.RSDWH_R1 = cpu.SDW->R1;
 266 
 267 ////////////////////////////////////////
 268 //
 269 // Sheet 3: "B"
 270 //
 271 ////////////////////////////////////////
 272 
 273 //
 274 // B: Check the ring
 275 //
 276 
 277   DBGAPP ("doAppendCycleOperandRead(B)\r\n");
 278 
 279   // check ring bracket consistency
 280 
 281   //C(SDW.R1) <= C(SDW.R2) <= C(SDW .R3)?
 282   if (! (cpu.SDW->R1 <= cpu.SDW->R2 && cpu.SDW->R2 <= cpu.SDW->R3)) {
 283     // Set fault ACV0 = IRO
 284     cpu.acvFaults |= ACV0;
 285     PNL (L68_ (cpu.apu.state |= apu_FLT;))
 286     FMSG (acvFaultsMsg = "acvFaults(B) C(SDW.R1) <= C(SDW.R2) <= " "C(SDW .R3)";)
 287   }
 288 
 289   // lastCycle == RTCD_OPERAND_FETCH
 290   // if a fault happens between the RTCD_OPERAND_FETCH and the INSTRUCTION_FETCH
 291   // of the next instruction - this happens about 35 time for just booting  and
 292   // shutting down multics -- a stored lastCycle is useless.
 293   // the opcode is preserved across faults and only replaced as the
 294   // INSTRUCTION_FETCH succeeds.
 295   if (lastCycle == RTCD_OPERAND_FETCH)
 296     sim_warn ("%s: lastCycle == RTCD_OPERAND_FETCH opcode %0#o\r\n", __func__, i->opcode);
 297 
 298   //
 299   // B1: The operand is one of: an instruction, data to be read or data to be
 300   //     written
 301   //
 302 
 303   // Is OPCODE call6?
 304   if (i->info->flags & CALL6_INS)
 305     goto E;
 306 
 307   // Transfer
 308   if (i->info->flags & TRANSFER_INS)
 309     goto F;
 310 
 311   //
 312   // check read bracket for read access
 313   //
 314 
 315   DBGAPP ("doAppendCycleOperandRead(B):!STR-OP\r\n");
 316 
 317   // No
 318   // C(TPR.TRR) > C(SDW .R2)?
 319   if (cpu.TPR.TRR > cpu.SDW->R2) {
 320     DBGAPP ("ACV3\r\n");
 321     DBGAPP ("doAppendCycleOperandRead(B) ACV3\r\n");
 322     //Set fault ACV3 = ORB
 323     cpu.acvFaults |= ACV3;
 324     PNL (L68_ (cpu.apu.state |= apu_FLT;))
 325     FMSG (acvFaultsMsg = "acvFaults(B) C(TPR.TRR) > C(SDW .R2)";)
 326   }
 327 
 328   if (cpu.SDW->R == 0) {
 329     // isolts 870
 330     cpu.TPR.TRR = cpu.PPR.PRR;
 331 
 332     //C(PPR.PSR) = C(TPR.TSR)?
 333     if (cpu.PPR.PSR != cpu.TPR.TSR) {
 334       DBGAPP ("ACV4\r\n");
 335       DBGAPP ("doAppendCycleOperandRead(B) ACV4\r\n");
 336       //Set fault ACV4 = R-OFF
 337       cpu.acvFaults |= ACV4;
 338       PNL (L68_ (cpu.apu.state |= apu_FLT;))
 339       FMSG (acvFaultsMsg = "acvFaults(B) C(PPR.PSR) = C(TPR.TSR)";)
 340     //} else {
 341       // sim_warn ("doAppendCycleOperandRead(B) SDW->R == 0 && cpu.PPR.PSR == cpu.TPR.TSR: %0#o\r\n", cpu.PPR.PSR);
 342     }
 343   }
 344 
 345   goto G;
 346 
 347 ////////////////////////////////////////
 348 //
 349 // Sheet 4: "C" "D"
 350 //
 351 ////////////////////////////////////////
 352 
 353 D:;
 354   DBGAPP ("doAppendCycleOperandRead(D)\r\n");
 355 
 356   // transfer or instruction fetch
 357 
 358   // check ring alarm to catch outbound transfers
 359 
 360   if (cpu.rRALR == 0)
 361     goto G;
 362 
 363   // C(PPR.PRR) < RALR?
 364   if (! (cpu.PPR.PRR < cpu.rRALR)) {
 365     DBGAPP ("ACV13\r\n");
 366     DBGAPP ("acvFaults(D) C(PPR.PRR) %o < RALR %o\r\n", cpu.PPR.PRR, cpu.rRALR);
 367     cpu.acvFaults |= ACV13;
 368     PNL (L68_ (cpu.apu.state |= apu_FLT;))
 369     FMSG (acvFaultsMsg = "acvFaults(D) C(PPR.PRR) < RALR";)
 370   }
 371 
 372   goto G;
 373 
 374 ////////////////////////////////////////
 375 //
 376 // Sheet 5: "E"
 377 //
 378 ////////////////////////////////////////
 379 
 380 E:;
 381 
 382   //
 383   // check ring bracket for instruction fetch after call6 instruction
 384   //   (this is the call6 read operand)
 385   //
 386 
 387   DBGAPP ("doAppendCycleOperandRead(E): CALL6\r\n");
 388   DBGAPP ("doAppendCycleOperandRead(E): E %o G %o PSR %05o TSR %05o CA %06o " "EB %06o R %o%o%o TRR %o PRR %o\r\n",
 389           cpu.SDW->E,  cpu.SDW->G,  cpu.PPR.PSR, cpu.TPR.TSR, cpu.TPR.CA, cpu.SDW->EB,
 390           cpu.SDW->R1, cpu.SDW->R2, cpu.SDW->R3, cpu.TPR.TRR, cpu.PPR.PRR);
 391 
 392   //SDW.E set ON?
 393   if (! cpu.SDW->E) {
 394     DBGAPP ("ACV2 b\r\n");
 395     DBGAPP ("doAppendCycleOperandRead(E) ACV2\r\n");
 396     // Set fault ACV2 = E-OFF
 397     cpu.acvFaults |= ACV2;
 398     PNL (L68_ (cpu.apu.state |= apu_FLT;))
 399     FMSG (acvFaultsMsg = "acvFaults(E) SDW .E set OFF";)
 400   }
 401 
 402   //SDW .G set ON?
 403   if (cpu.SDW->G)
 404     goto E1;
 405 
 406   // C(PPR.PSR) = C(TPR.TSR)?
 407   if (cpu.PPR.PSR == cpu.TPR.TSR && ! TST_I_ABS)
 408     goto E1;
 409 
 410   // XXX This doesn't seem right
 411   // EB is word 15; masking address makes no sense; rather 0-extend EB
 412   // Fixes ISOLTS 880-01
 413   if (cpu.TPR.CA >= (word18) cpu.SDW->EB) {
 414     DBGAPP ("ACV7\r\n");
 415     DBGAPP ("doAppendCycleOperandRead(E) ACV7\r\n");
 416     // Set fault ACV7 = NO GA
 417     cpu.acvFaults |= ACV7;
 418     PNL (L68_ (cpu.apu.state |= apu_FLT;))
 419     FMSG (acvFaultsMsg = "acvFaults(E) TPR.CA4-17 >= SDW.CL";)
 420   }
 421 
 422 E1:
 423   DBGAPP ("doAppendCycleOperandRead(E1): CALL6 (cont'd)\r\n");
 424 
 425   // C(TPR.TRR) > SDW.R3?
 426   if (cpu.TPR.TRR > cpu.SDW->R3) {
 427     DBGAPP ("ACV8\r\n");
 428     DBGAPP ("doAppendCycleOperandRead(E) ACV8\r\n");
 429     //Set fault ACV8 = OCB
 430     cpu.acvFaults |= ACV8;
 431     PNL (L68_ (cpu.apu.state |= apu_FLT;))
 432     FMSG (acvFaultsMsg = "acvFaults(E1) C(TPR.TRR) > SDW.R3";)
 433   }
 434 
 435   // C(TPR.TRR) < SDW.R1?
 436   if (cpu.TPR.TRR < cpu.SDW->R1) {
 437     DBGAPP ("ACV9\r\n");
 438     DBGAPP ("doAppendCycleOperandRead(E) ACV9\r\n");
 439     // Set fault ACV9 = OCALL
 440     cpu.acvFaults |= ACV9;
 441     PNL (L68_ (cpu.apu.state |= apu_FLT;))
 442     FMSG (acvFaultsMsg = "acvFaults(E1) C(TPR.TRR) < SDW.R1";)
 443   }
 444 
 445   // C(TPR.TRR) > C(PPR.PRR)?
 446   if (cpu.TPR.TRR > cpu.PPR.PRR) {
 447     // C(PPR.PRR) < SDW.R2?
 448     if (cpu.PPR.PRR < cpu.SDW->R2) {
 449       DBGAPP ("ACV10\r\n");
 450       DBGAPP ("doAppendCycleOperandRead(E) ACV10\r\n");
 451       // Set fault ACV10 = BOC
 452       cpu.acvFaults |= ACV10;
 453       PNL (L68_ (cpu.apu.state |= apu_FLT;))
 454       FMSG (acvFaultsMsg = "acvFaults(E1) C(TPR.TRR) > C(PPR.PRR) && " "C(PPR.PRR) < SDW.R2";)
 455     }
 456   }
 457 
 458   DBGAPP ("doAppendCycleOperandRead(E1): CALL6 TPR.TRR %o SDW->R2 %o\r\n", cpu.TPR.TRR, cpu.SDW->R2);
 459 
 460   // C(TPR.TRR) > SDW.R2?
 461   if (cpu.TPR.TRR > cpu.SDW->R2) {
 462     // SDW.R2 -> C(TPR.TRR)
 463     cpu.TPR.TRR = cpu.SDW->R2;
 464   }
 465 
 466   DBGAPP ("doAppendCycleOperandRead(E1): CALL6 TPR.TRR %o\r\n", cpu.TPR.TRR);
 467 
 468   goto G;
 469 
 470 ////////////////////////////////////////
 471 //
 472 // Sheet 6: "F"
 473 //
 474 ////////////////////////////////////////
 475 
 476 F:;
 477   PNL (L68_ (cpu.apu.state |= apu_PIAU;))
 478   DBGAPP ("doAppendCycleOperandRead(F): transfer or instruction fetch\r\n");
 479 
 480   //
 481   // check ring bracket for instruction fetch
 482   //
 483 
 484   // C(TPR.TRR) < C(SDW .R1)?
 485   // C(TPR.TRR) > C(SDW .R2)?
 486   if (cpu.TPR.TRR < cpu.SDW->R1 || cpu.TPR.TRR > cpu.SDW->R2) {
 487     DBGAPP ("ACV1 a/b\r\n");
 488     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);
 489     cpu.acvFaults |= ACV1;
 490     PNL (L68_ (cpu.apu.state |= apu_FLT;))
 491     FMSG (acvFaultsMsg = "acvFaults(F) C(TPR.TRR) < C(SDW .R1)";)
 492   }
 493   // SDW .E set ON?
 494   if (! cpu.SDW->E) {
 495     DBGAPP ("ACV2 c\r\n");
 496     DBGAPP ("doAppendCycleOperandRead(F) ACV2\r\n");
 497     cpu.acvFaults |= ACV2;
 498     PNL (L68_ (cpu.apu.state |= apu_FLT;))
 499     FMSG (acvFaultsMsg = "acvFaults(F) SDW .E set OFF";)
 500   }
 501 
 502   // C(PPR.PRR) = C(TPR.TRR)?
 503   if (cpu.PPR.PRR != cpu.TPR.TRR) {
 504     DBGAPP ("ACV12\r\n");
 505     DBGAPP ("doAppendCycleOperandRead(F) ACV12\r\n");
 506     //Set fault ACV12 = CRT
 507     cpu.acvFaults |= ACV12;
 508     PNL (L68_ (cpu.apu.state |= apu_FLT;))
 509     FMSG (acvFaultsMsg = "acvFaults(F) C(PPR.PRR) != C(TPR.TRR)";)
 510   }
 511 
 512   goto D;
 513 
 514 ////////////////////////////////////////
 515 //
 516 // Sheet 7: "G"
 517 //
 518 ////////////////////////////////////////
 519 
 520 G:;
 521 
 522   DBGAPP ("doAppendCycleOperandRead(G)\r\n");
 523 
 524   //C(TPR.CA)0,13 > SDW.BOUND?
 525   if (((cpu.TPR.CA >> 4) & 037777) > cpu.SDW->BOUND) {
 526     DBGAPP ("ACV15\r\n");
 527     DBGAPP ("doAppendCycleOperandRead(G) ACV15\r\n");
 528     cpu.acvFaults |= ACV15;
 529     PNL (L68_ (cpu.apu.state |= apu_FLT;))
 530     FMSG (acvFaultsMsg = "acvFaults(G) C(TPR.CA)0,13 > SDW.BOUND";)
 531     DBGAPP ("acvFaults(G) C(TPR.CA)0,13 > SDW.BOUND\r\n" "   CA %06o CA>>4 & 037777 %06o SDW->BOUND %06o",
 532             cpu.TPR.CA, ((cpu.TPR.CA >> 4) & 037777), cpu.SDW->BOUND);
 533   }
 534   bound = cpu.SDW->BOUND;
 535   p = cpu.SDW->P;
 536 
 537   if (cpu.acvFaults) {
 538     DBGAPP ("doAppendCycleOperandRead(G) acvFaults\r\n");
 539     PNL (L68_ (cpu.apu.state |= apu_FLT;))
 540     // Initiate an access violation fault
 541     doFault (FAULT_ACV, (_fault_subtype) {.fault_acv_subtype=cpu.acvFaults},
 542             "ACV fault");
 543   }
 544 
 545   // is segment C(TPR.TSR) paged?
 546   if (cpu.SDW->U)
 547     goto H; // Not paged
 548 
 549   // Yes. segment is paged ...
 550   // is PTW for C(TPR.CA) in PTWAM?
 551 
 552   DBGAPP ("doAppendCycleOperandRead(G) CA %06o\r\n", cpu.TPR.CA);
 553   if (nomatch ||
 554       ! fetch_ptw_from_ptwam (cpup, cpu.SDW->POINTER, cpu.TPR.CA)) {
 555     fetch_ptw (cpup, cpu.SDW, cpu.TPR.CA);
 556     if (! cpu.PTW0.DF) {
 557       // initiate a directed fault
 558       doFault (FAULT_DF0 + cpu.PTW0.FC, (_fault_subtype) {.bits=0},
 559               "PTW0.F == 0");
 560     }
 561     loadPTWAM (cpup, cpu.SDW->POINTER, cpu.TPR.CA, nomatch); // load PTW0 to PTWAM
 562   }
 563 
 564   // Prepage mode?
 565   // check for "uninterruptible" EIS instruction
 566   // ISOLTS-878 02: mvn,cmpn,mvne,ad3d; obviously also
 567   // ad2/3d,sb2/3d,mp2/3d,dv2/3d
 568   // DH03 p.8-13: probably also mve,btd,dtb
 569   if (i->opcodeX && ((i->opcode & 0770)== 0200|| (i->opcode & 0770) == 0220
 570       || (i->opcode & 0770)== 020|| (i->opcode & 0770) == 0300)) {
 571     do_ptw2 (cpup, cpu.SDW, cpu.TPR.CA);
 572   }
 573   goto I;
 574 
 575 ////////////////////////////////////////
 576 //
 577 // Sheet 8: "H", "I"
 578 //
 579 ////////////////////////////////////////
 580 
 581 H:;
 582   DBGAPP ("doAppendCycleOperandRead(H): FANP\r\n");
 583 
 584   paged = false;
 585 
 586   PNL (L68_ (cpu.apu.state |= apu_FANP;))
 587 
 588 
 589 
 590 
 591 
 592 
 593 
 594   set_apu_status (cpup, apuStatus_FANP);
 595 #if defined(HDBG)
 596   hdbgNote ("doAppendCycleOperandRead", "FANP");
 597 #endif /* if defined(HDBG) */
 598   DBGAPP ("doAppendCycleOperandRead(H): SDW->ADDR=%08o CA=%06o\r\n",
 599           cpu.SDW->ADDR, cpu.TPR.CA);
 600 
 601   pageAddress = (cpu.SDW->ADDR & 077777760);
 602   finalAddress = (cpu.SDW->ADDR & 077777760) + cpu.TPR.CA;
 603   finalAddress &= 0xffffff;
 604   PNL (cpu.APUMemAddr = finalAddress;)
 605 
 606   DBGAPP ("doAppendCycleOperandRead(H:FANP): (%05o:%06o) finalAddress=%08o\r\n",
 607           cpu.TPR.TSR, cpu.TPR.CA, finalAddress);
 608 
 609   goto HI;
 610 
 611 I:;
 612 
 613 // Set PTW.M
 614 
 615   DBGAPP ("doAppendCycleOperandRead(I): FAP\r\n");
 616 
 617   paged = true;
 618 
 619 #if defined(HDBG)
 620   hdbgNote ("doAppendCycleOperandRead", "FAP");
 621 #endif /* if defined(HDBG) */
 622   // final address paged
 623   set_apu_status (cpup, apuStatus_FAP);
 624   PNL (L68_ (cpu.apu.state |= apu_FAP;))
 625 
 626   word24 y2 = cpu.TPR.CA % 1024;
 627 
 628   pageAddress = (((word24)cpu.PTW->ADDR & 0777760) << 6);
 629   // AL39: The hardware ignores low order bits of the main memory page
 630   // address according to page size
 631   finalAddress = (((word24)cpu.PTW->ADDR & 0777760) << 6) + y2;
 632   finalAddress &= 0xffffff;
 633   PNL (cpu.APUMemAddr = finalAddress;)
 634 
 635   L68_ (
 636     if (cpu.MR_cache.emr && cpu.MR_cache.ihr)
 637       add_l68_APU_history (cpup, APUH_FAP);
 638   )
 639 
 640   DBGAPP ("doAppendCycleOperandRead(H:FAP): (%05o:%06o) finalAddress=%08o\r\n",
 641           cpu.TPR.TSR, cpu.TPR.CA, finalAddress);
 642 
 643   //goto HI;
 644 
 645 HI:
 646   DBGAPP ("doAppendCycleOperandRead(HI)\r\n");
 647 
 648 #if defined(TEST_UCACHE)
 649   if (cacheHit) {
 650     bool err = false;
 651     if (cachedAddress != pageAddress) {
 652      sim_printf ("cachedAddress %08o != pageAddress %08o\r\n",
 653              cachedAddress, pageAddress);
 654      err = true;
 655     }
 656     if (cachedR1 != RSDWH_R1) {
 657       sim_printf ("cachedR1 %01o != RSDWH_R1 %01o\r\n",
 658               cachedR1, RSDWH_R1);
 659       err = true;
 660     }
 661     if (cachedBound != bound) {
 662       sim_printf ("cachedBound %01o != bound %01o\r\n",
 663               cachedBound, bound);
 664       err = true;
 665     }
 666     if (cachedPaged != paged) {
 667       sim_printf ("cachedPaged %01o != paged %01o\r\n",
 668               cachedPaged, paged);
 669       err = true;
 670     }
 671     if (err) {
 672 # if defined(HDBG)
 673       HDBGPrint ();
 674 # endif /* if defined(HDBG) */
 675       sim_printf ("oprnd read err  %d %05o:%06o\r\n",
 676               evcnt, cpu.TPR.TSR, cpu.TPR.CA);
 677       exit (1);
 678     }
 679     //sim_printf ("hit  %d %05o:%06o\r\n", evcnt, cpu.TPR.TSR, cpu.TPR.CA);
 680 # if defined(HDBG)
 681     hdbgNote ("doAppendCycleOperandRead.h", "test hit %d %05o:%06o\r\n",
 682             evcnt, cpu.TPR.TSR, cpu.TPR.CA);
 683 # endif /* if defined(HDBG) */
 684   } else {
 685     //sim_printf ("miss %d %05o:%06o\r\n", evcnt, cpu.TPR.TSR, cpu.TPR.CA);
 686 # if defined(HDBG)
 687     hdbgNote ("doAppendCycleOperandRead.h", "test miss %d %05o:%06o\r\n",
 688             evcnt, cpu.TPR.TSR, cpu.TPR.CA);
 689 # endif /* if defined(HDBG) */
 690   }
 691 #endif
 692 
 693   ucCacheSave (cpup, this, cpu.TPR.TSR, cpu.TPR.CA, bound, p, pageAddress, RSDWH_R1, paged);
 694 #if defined(TEST_UCACHE)
 695 # if defined(HDBG)
 696   hdbgNote ("doAppendCycleOperandRead.h", "cache %d %u %05o:%06o %05o %o %08o %o %o",
 697           evcnt, this, cpu.TPR.TSR, cpu.TPR.CA, bound, p, pageAddress, RSDWH_R1, paged);
 698 # endif /* if defined(HDBG) */
 699 #endif /* if defined(TEST_UCACHE) */
 700 evcnt ++;
 701 
 702   // isolts 870
 703   cpu.cu.XSF = 1;
 704   if (cpu.currentInstruction.b29)
 705     cpu.xsfScu = true;
 706   sim_debug (DBG_TRACEEXT, & cpu_dev, "loading of cpu.TPR.TSR sets XSF to 1\r\n");
 707 
 708   core_readN (cpup, finalAddress, data, nWords, "OPERAND_READ");
 709 
 710   if (i->info->flags & CALL6_INS)
 711     goto N;
 712 
 713   // Transfer or instruction fetch?
 714   if (i->info->flags & TRANSFER_INS)
 715     goto L;
 716 
 717   // APU data movement?
 718   //  handled above
 719   goto Exit;
 720 
 721 ////////////////////////////////////////
 722 //
 723 // Sheet 10: "K", "L", "M", "N"
 724 //
 725 ////////////////////////////////////////
 726 
 727 L:; // Transfer or instruction fetch
 728 
 729   DBGAPP ("doAppendCycleOperandRead(L)\r\n");
 730 
 731   // Is OPCODE tspn?
 732   if (i->info->flags & TSPN_INS) {
 733     if (i->opcode <= 0273)
 734       n = (i->opcode & 3);
 735     else
 736       n = (i->opcode & 3) + 4;
 737 
 738     // C(PPR.PRR) -> C(PRn .RNR)
 739     // C(PPR.PSR) -> C(PRn .SNR)
 740     // C(PPR.IC) -> C(PRn .WORDNO)
 741     // 000000 -> C(PRn .BITNO)
 742     cpu.PR[n].RNR = cpu.PPR.PRR;
 743 // According the AL39, the PSR is 'undefined' in absolute mode.
 744 // ISOLTS thinks means don't change the operand
 745     if (get_addr_mode (cpup) == APPEND_mode)
 746       cpu.PR[n].SNR = cpu.PPR.PSR;
 747     cpu.PR[n].WORDNO = (cpu.PPR.IC + 1) & MASK18;
 748     SET_PR_BITNO (n, 0);
 749 #if defined(TESTING)
 750     HDBGRegPRW (n, "app tspn");
 751 #endif /* if defined(TESTING) */
 752   }
 753 
 754 // KL:
 755   DBGAPP ("doAppendCycleOperandRead(KL)\r\n");
 756 
 757   // C(TPR.TSR) -> C(PPR.PSR)
 758   cpu.PPR.PSR = cpu.TPR.TSR;
 759   // C(TPR.CA) -> C(PPR.IC)
 760   cpu.PPR.IC = cpu.TPR.CA;
 761 
 762   //goto M;
 763 
 764 M: // Set P
 765   DBGAPP ("doAppendCycleOperandRead(M)\r\n");
 766 
 767   // C(TPR.TRR) = 0?
 768   if (cpu.TPR.TRR == 0) {
 769     // C(SDW.P) -> C(PPR.P)
 770     cpu.PPR.P = p;
 771   } else {
 772     // 0 C(PPR.P)
 773     cpu.PPR.P = 0;
 774   }
 775 
 776   goto Exit;
 777 
 778 N: // CALL6
 779   DBGAPP ("doAppendCycleOperandRead(N)\r\n");
 780 
 781   // C(TPR.TRR) = C(PPR.PRR)?
 782   if (cpu.TPR.TRR == cpu.PPR.PRR) {
 783     // C(PR6.SNR) -> C(PR7.SNR)
 784     cpu.PR[7].SNR = cpu.PR[6].SNR;
 785     DBGAPP ("doAppendCycleOperandRead(N) PR7.SNR = PR6.SNR %05o\r\n", cpu.PR[7].SNR);
 786   } else {
 787     // C(DSBR.STACK) || C(TPR.TRR) -> C(PR7.SNR)
 788     cpu.PR[7].SNR = ((word15) (cpu.DSBR.STACK << 3)) | cpu.TPR.TRR;
 789     DBGAPP ("doAppendCycleOperandRead(N) STACK %05o TRR %o\r\n", cpu.DSBR.STACK, cpu.TPR.TRR);
 790     DBGAPP ("doAppendCycleOperandRead(N) PR7.SNR = STACK||TRR  %05o\r\n", cpu.PR[7].SNR);
 791   }
 792 
 793   // C(TPR.TRR) -> C(PR7.RNR)
 794   cpu.PR[7].RNR = cpu.TPR.TRR;
 795   // 00...0 -> C(PR7.WORDNO)
 796   cpu.PR[7].WORDNO = 0;
 797   // 000000 -> C(PR7.BITNO)
 798   SET_PR_BITNO (7, 0);
 799 #if defined(TESTING)
 800   HDBGRegPRW (7, "app call6");
 801 #endif /* if defined(TESTING) */
 802   // C(TPR.TRR) -> C(PPR.PRR)
 803   cpu.PPR.PRR = cpu.TPR.TRR;
 804   // C(TPR.TSR) -> C(PPR.PSR)
 805   cpu.PPR.PSR = cpu.TPR.TSR;
 806   // C(TPR.CA) -> C(PPR.IC)
 807   cpu.PPR.IC = cpu.TPR.CA;
 808 
 809   goto M;
 810 
 811 Exit:;
 812 
 813   PNL (cpu.APUDataBusOffset = cpu.TPR.CA;)
 814   PNL (cpu.APUDataBusAddr = finalAddress;)
 815 
 816   PNL (L68_ (cpu.apu.state |= apu_FA;))
 817 
 818   DBGAPP ("doAppendCycleOperandRead (Exit) PRR %o PSR %05o P %o IC %06o\r\n", cpu.PPR.PRR, cpu.PPR.PSR, cpu.PPR.P, cpu.PPR.IC);
 819   DBGAPP ("doAppendCycleOperandRead (Exit) TRR %o TSR %05o TBR %02o CA %06o\r\n", cpu.TPR.TRR, cpu.TPR.TSR, cpu.TPR.TBR, cpu.TPR.CA);
 820 
 821   return finalAddress;    // or 0 or -1???
 822 }
 823 #undef TEST_UCACHE

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