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

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