root/src/dps8/doAppendCycleRTCDOperandFetch.h

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

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. doAppendCycleRTCDOperandFetch

   1 /*
   2  * vim: filetype=c:tabstop=4:ai:expandtab
   3  * SPDX-License-Identifier: ICU
   4  * scspell-id: 24c12472-171d-11ee-b2a6-80ee73e9b8e7
   5  *
   6  * ---------------------------------------------------------------------------
   7  *
   8  * Copyright (c) 2022-2023 Charles Anthony
   9  * Copyright (c) 2022-2023 Jeffrey H. Johnson
  10  * Copyright (c) 2022-2024 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 word24 doAppendCycleRTCDOperandFetch (cpu_state_t * cpup, word36 * data, uint nWords) {
     /* [previous][next][first][last][top][bottom][index][help] */
  19   DCDstruct * i = & cpu.currentInstruction;
  20   DBGAPP ("doAppendCycleRTCDOperandFetch(Entry) thisCycle=RTCD_OPERAND_FETCH\n");
  21   DBGAPP ("doAppendCycleRTCDOperandFetch(Entry) lastCycle=%s\n", str_pct (cpu.apu.lastCycle));
  22   DBGAPP ("doAppendCycleRTCDOperandFetch(Entry) CA %06o\n", cpu.TPR.CA);
  23   DBGAPP ("doAppendCycleRTCDOperandFetch(Entry) n=%2u\n", nWords);
  24   DBGAPP ("doAppendCycleRTCDOperandFetch(Entry) PPR.PRR=%o PPR.PSR=%05o\n", cpu.PPR.PRR, cpu.PPR.PSR);
  25   DBGAPP ("doAppendCycleRTCDOperandFetch(Entry) TPR.TRR=%o TPR.TSR=%05o\n", cpu.TPR.TRR, cpu.TPR.TSR);
  26 
  27   if (i->b29) {
  28     DBGAPP ("doAppendCycleRTCDOperandFetch(Entry) isb29 PRNO %o\n", GET_PRN (IWB_IRODD));
  29   }
  30 
  31   bool nomatch = true;
  32   if (cpu.tweaks.enable_wam) {
  33     // AL39: The associative memory is ignored (forced to "no match") during
  34     // address preparation.
  35     // lptp,lptr,lsdp,lsdr,sptp,sptr,ssdp,ssdr
  36     // Unfortunately, ISOLTS doesn't try to execute any of these in append mode.
  37     // XXX should this be only for OPERAND_READ and OPERAND_STORE?
  38     nomatch = ((i->opcode == 0232 || i->opcode == 0254 ||
  39                 i->opcode == 0154 || i->opcode == 0173) &&
  40                 i->opcodeX ) ||
  41                ((i->opcode == 0557 || i->opcode == 0257) &&
  42                 ! i->opcodeX);
  43   }
  44 
  45   processor_cycle_type lastCycle = cpu.apu.lastCycle;
  46   cpu.apu.lastCycle = RTCD_OPERAND_FETCH;
  47 
  48   DBGAPP ("doAppendCycleRTCDOperandFetch(Entry) XSF %o\n", cpu.cu.XSF);
  49 
  50   PNL (L68_ (cpu.apu.state = 0;))
  51 
  52   cpu.RSDWH_R1 = 0;
  53 
  54   cpu.acvFaults = 0;
  55 
  56 //#define FMSG(x) x
  57 #define FMSG(x)
  58   FMSG (char * acvFaultsMsg = "<unknown>";)
  59 
  60   word24 finalAddress = (word24) -1;  // not everything requires a final
  61                                       // address
  62 
  63 ////////////////////////////////////////
  64 //
  65 // Sheet 1: "START APPEND"
  66 //
  67 ////////////////////////////////////////
  68 
  69 // START APPEND
  70 
  71   // If the rtcd instruction is executed with the processor in absolute
  72   // mode with bit 29 of the instruction word set OFF and without
  73   // indirection through an ITP or ITS pair, then:
  74   //
  75   //   appending mode is entered for address preparation for the
  76   //   rtcd operand and is retained if the instruction executes
  77   //   successfully, and the effective segment number generated for
  78   //   the SDW fetch and subsequent loading into C(TPR.TSR) is equal
  79   //   to C(PPR.PSR) and may be undefined in absolute mode, and the
  80   //   effective ring number loaded into C(TPR.TRR) prior to the SDW
  81   //   fetch is equal to C(PPR.PRR) (which is 0 in absolute mode)
  82   //   implying that control is always transferred into ring 0.
  83   //
  84   if (get_addr_mode(cpup) == ABSOLUTE_mode && ! (cpu.cu.XSF || cpu.currentInstruction.b29)) {
  85     cpu.TPR.TSR = 0;
  86     DBGAPP ("RTCD_OPERAND_FETCH ABSOLUTE mode set TSR %05o TRR %o\n", cpu.TPR.TSR, cpu.TPR.TRR);
  87   }
  88 
  89   goto A;
  90 
  91 ////////////////////////////////////////
  92 //
  93 // Sheet 2: "A"
  94 //
  95 ////////////////////////////////////////
  96 
  97 //
  98 //  A:
  99 //    Get SDW
 100 
 101 A:;
 102 
 103   //PNL (cpu.APUMemAddr = address;)
 104   PNL (cpu.APUMemAddr = cpu.TPR.CA;)
 105 
 106   DBGAPP ("doAppendCycleRTCDOperandFetch(A)\n");
 107 
 108   // is SDW for C(TPR.TSR) in SDWAM?
 109   if (nomatch || ! fetch_sdw_from_sdwam (cpup, cpu.TPR.TSR)) {
 110     // No
 111     DBGAPP ("doAppendCycleRTCDOperandFetch(A):SDW for segment %05o not in SDWAM\n", cpu.TPR.TSR);
 112     DBGAPP ("doAppendCycleRTCDOperandFetch(A):DSBR.U=%o\n", cpu.DSBR.U);
 113 
 114     if (cpu.DSBR.U == 0) {
 115       fetch_dsptw (cpup, cpu.TPR.TSR);
 116 
 117       if (! cpu.PTW0.DF)
 118         doFault (FAULT_DF0 + cpu.PTW0.FC, fst_zero, "doAppendCycleRTCDOperandFetch(A): PTW0.F == 0");
 119 
 120       if (! cpu.PTW0.U)
 121         modify_dsptw (cpup, cpu.TPR.TSR);
 122 
 123       fetch_psdw (cpup, cpu.TPR.TSR);
 124     } else
 125       fetch_nsdw (cpup, cpu.TPR.TSR); // load SDW0 from descriptor segment table.
 126 
 127     if (cpu.SDW0.DF == 0) {
 128       DBGAPP ("doAppendCycleRTCDOperandFetch(A): SDW0.F == 0! " "Initiating directed fault\n");
 129       // initiate a directed fault ...
 130       doFault (FAULT_DF0 + cpu.SDW0.FC, fst_zero, "SDW0.F == 0");
 131     }
 132     // load SDWAM .....
 133     load_sdwam (cpup, cpu.TPR.TSR, nomatch);
 134   }
 135   DBGAPP ("doAppendCycleRTCDOperandFetch(A) R1 %o R2 %o R3 %o E %o\n", cpu.SDW->R1, cpu.SDW->R2, cpu.SDW->R3, cpu.SDW->E);
 136 
 137   // Yes...
 138   cpu.RSDWH_R1 = cpu.SDW->R1;
 139 
 140 ////////////////////////////////////////
 141 //
 142 // Sheet 3: "B"
 143 //
 144 ////////////////////////////////////////
 145 
 146 //
 147 // B: Check the ring
 148 //
 149 
 150   DBGAPP ("doAppendCycleRTCDOperandFetch(B)\n");
 151 
 152   // check ring bracket consistency
 153 
 154   //C(SDW.R1) <= C(SDW.R2) <= C(SDW .R3)?
 155   if (! (cpu.SDW->R1 <= cpu.SDW->R2 && cpu.SDW->R2 <= cpu.SDW->R3)) {
 156     // Set fault ACV0 = IRO
 157     cpu.acvFaults |= ACV0;
 158     PNL (L68_ (cpu.apu.state |= apu_FLT;))
 159     FMSG (acvFaultsMsg = "acvFaults(B) C(SDW.R1) <= C(SDW.R2) <= C(SDW .R3)";)
 160   }
 161 
 162   if (lastCycle == RTCD_OPERAND_FETCH)
 163     sim_warn ("%s: lastCycle == RTCD_OPERAND_FETCH opcode %0#o\n", __func__, i->opcode);
 164 
 165   //
 166   // B1: The operand is one of: an instruction, data to be read or data to be
 167   //     written
 168   //
 169 
 170   //
 171   // check read bracket for read access
 172   //
 173 
 174   DBGAPP ("doAppendCycleRTCDOperandFetch(B):!STR-OP\n");
 175 
 176   // No
 177   // C(TPR.TRR) > C(SDW .R2)?
 178   if (cpu.TPR.TRR > cpu.SDW->R2) {
 179     DBGAPP ("ACV3\n");
 180     DBGAPP ("doAppendCycleRTCDOperandFetch(B) ACV3\n");
 181     //Set fault ACV3 = ORB
 182     cpu.acvFaults |= ACV3;
 183     PNL (L68_ (cpu.apu.state |= apu_FLT;))
 184     FMSG (acvFaultsMsg = "acvFaults(B) C(TPR.TRR) > C(SDW .R2)";)
 185   }
 186 
 187   if (cpu.SDW->R == 0) {
 188     // isolts 870
 189     cpu.TPR.TRR = cpu.PPR.PRR;
 190 
 191     //C(PPR.PSR) = C(TPR.TSR)?
 192     if (cpu.PPR.PSR != cpu.TPR.TSR) {
 193       DBGAPP ("ACV4\n");
 194       DBGAPP ("doAppendCycleRTCDOperandFetch(B) ACV4\n");
 195       //Set fault ACV4 = R-OFF
 196       cpu.acvFaults |= ACV4;
 197       PNL (L68_ (cpu.apu.state |= apu_FLT;))
 198       FMSG (acvFaultsMsg = "acvFaults(B) C(PPR.PSR) = C(TPR.TSR)";)
 199     //} else {
 200       // sim_warn ("doAppendCycleRTCDOperandFetch(B) SDW->R == 0 && cpu.PPR.PSR == cpu.TPR.TSR: %0#o\n", cpu.PPR.PSR);
 201     }
 202   }
 203 
 204   goto G;
 205 
 206 ////////////////////////////////////////
 207 //
 208 // Sheet 7: "G"
 209 //
 210 ////////////////////////////////////////
 211 
 212 G:;
 213 
 214   DBGAPP ("doAppendCycleRTCDOperandFetch(G)\n");
 215 
 216   //C(TPR.CA)0,13 > SDW.BOUND?
 217   if (((cpu.TPR.CA >> 4) & 037777) > cpu.SDW->BOUND) {
 218     DBGAPP ("ACV15\n");
 219     DBGAPP ("doAppendCycleRTCDOperandFetch(G) ACV15\n");
 220     cpu.acvFaults |= ACV15;
 221     PNL (L68_ (cpu.apu.state |= apu_FLT;))
 222     FMSG (acvFaultsMsg = "acvFaults(G) C(TPR.CA)0,13 > SDW.BOUND";)
 223     DBGAPP ("acvFaults(G) C(TPR.CA)0,13 > SDW.BOUND\n" "   CA %06o CA>>4 & 037777 %06o SDW->BOUND %06o",
 224             cpu.TPR.CA, ((cpu.TPR.CA >> 4) & 037777), cpu.SDW->BOUND);
 225     }
 226 
 227   if (cpu.acvFaults) {
 228     DBGAPP ("doAppendCycleRTCDOperandFetch(G) acvFaults\n");
 229     PNL (L68_ (cpu.apu.state |= apu_FLT;))
 230     // Initiate an access violation fault
 231     doFault (FAULT_ACV, (_fault_subtype) {.fault_acv_subtype=cpu.acvFaults}, "ACV fault");
 232   }
 233 
 234   // is segment C(TPR.TSR) paged?
 235   if (cpu.SDW->U)
 236     goto H; // Not paged
 237 
 238   // Yes. segment is paged ...
 239   // is PTW for C(TPR.CA) in PTWAM?
 240 
 241   DBGAPP ("doAppendCycleRTCDOperandFetch(G) CA %06o\n", cpu.TPR.CA);
 242   if (nomatch || ! fetch_ptw_from_ptwam (cpup, cpu.SDW->POINTER, cpu.TPR.CA)) {
 243     fetch_ptw (cpup, cpu.SDW, cpu.TPR.CA);
 244     if (! cpu.PTW0.DF) {
 245       // initiate a directed fault
 246       doFault (FAULT_DF0 + cpu.PTW0.FC, (_fault_subtype) {.bits=0}, "PTW0.F == 0");
 247     }
 248     loadPTWAM (cpup, cpu.SDW->POINTER, cpu.TPR.CA, nomatch); // load PTW0 to PTWAM
 249   }
 250 
 251   // Prepage mode?
 252   // check for "uninterruptible" EIS instruction
 253   // ISOLTS-878 02: mvn,cmpn,mvne,ad3d; obviously also
 254   // ad2/3d,sb2/3d,mp2/3d,dv2/3d
 255   // DH03 p.8-13: probably also mve,btd,dtb
 256   if (i->opcodeX && ((i->opcode & 0770)== 0200|| (i->opcode & 0770) == 0220
 257       || (i->opcode & 0770)== 020|| (i->opcode & 0770) == 0300)) {
 258     do_ptw2 (cpup, cpu.SDW, cpu.TPR.CA);
 259   }
 260   goto I;
 261 
 262 ////////////////////////////////////////
 263 //
 264 // Sheet 8: "H", "I"
 265 //
 266 ////////////////////////////////////////
 267 
 268 H:;
 269   DBGAPP ("doAppendCycleRTCDOperandFetch(H): FANP\n");
 270 
 271   PNL (L68_ (cpu.apu.state |= apu_FANP;))
 272 
 273 
 274 
 275 
 276 
 277 
 278 
 279   set_apu_status (cpup, apuStatus_FANP);
 280 
 281   DBGAPP ("doAppendCycleRTCDOperandFetch(H): SDW->ADDR=%08o CA=%06o \n", cpu.SDW->ADDR, cpu.TPR.CA);
 282 
 283   if (get_addr_mode (cpup) == ABSOLUTE_mode && ! (cpu.cu.XSF || cpu.currentInstruction.b29)) {
 284     finalAddress = cpu.TPR.CA;
 285   } else {
 286     finalAddress = (cpu.SDW->ADDR & 077777760) + cpu.TPR.CA;
 287     finalAddress &= 0xffffff;
 288   }
 289   PNL (cpu.APUMemAddr = finalAddress;)
 290 
 291   DBGAPP ("doAppendCycleRTCDOperandFetch(H:FANP): (%05o:%06o) finalAddress=%08o\n", cpu.TPR.TSR, cpu.TPR.CA, finalAddress);
 292 
 293   goto HI;
 294 
 295 I:;
 296 
 297 // Set PTW.M
 298 
 299   DBGAPP ("doAppendCycleRTCDOperandFetch(I): FAP\n");
 300 
 301   // final address paged
 302   set_apu_status (cpup, apuStatus_FAP);
 303   PNL (L68_ (cpu.apu.state |= apu_FAP;))
 304 
 305   word24 y2 = cpu.TPR.CA % 1024;
 306 
 307   // AL39: The hardware ignores low order bits of the main memory page
 308   // address according to page size
 309   finalAddress = (((word24)cpu.PTW->ADDR & 0777760) << 6) + y2;
 310   finalAddress &= 0xffffff;
 311   PNL (cpu.APUMemAddr = finalAddress;)
 312 
 313 #if defined(L68)
 314   if (cpu.MR_cache.emr && cpu.MR_cache.ihr)
 315     add_APU_history (APUH_FAP);
 316 #endif /* if defined(L68) */
 317   DBGAPP ("doAppendCycleRTCDOperandFetch(H:FAP): (%05o:%06o) finalAddress=%08o\n", cpu.TPR.TSR, cpu.TPR.CA, finalAddress);
 318 
 319   goto HI;
 320 
 321 HI:
 322   DBGAPP ("doAppendCycleRTCDOperandFetch(HI)\n");
 323 
 324   // isolts 870
 325   cpu.cu.XSF = 1;
 326   sim_debug (DBG_TRACEEXT, & cpu_dev, "loading of cpu.TPR.TSR sets XSF to 1\n");
 327 
 328   core_readN (cpup, finalAddress, data, nWords, "RTCD_OPERAND_FETCH");
 329 
 330   goto K;
 331 
 332 ////////////////////////////////////////
 333 //
 334 // Sheet 10: "K", "L", "M", "N"
 335 //
 336 ////////////////////////////////////////
 337 
 338 K:; // RTCD operand fetch
 339   DBGAPP ("doAppendCycleRTCDOperandFetch(K)\n");
 340 
 341   word3 y = GET_ITS_RN (data);
 342 
 343   // C(Y-pair)3,17 -> C(PPR.PSR)
 344   // We set TSR here; TSR will be copied to PSR at KL
 345   cpu.TPR.TSR = GET_ITS_SEGNO (data);
 346 
 347   // Maximum of
 348   // C(Y-pair)18,20; C(TPR.TRR); C(SDW.R1) -> C(PPR.PRR)
 349   // We set TRR here as well
 350   cpu.PPR.PRR = cpu.TPR.TRR = max3 (y, cpu.TPR.TRR, cpu.RSDWH_R1);
 351 
 352   // C(Y-pair)36,53 -> C(PPR.IC)
 353   // We set CA here; copied to IC  at KL
 354   cpu.TPR.CA = GET_ITS_WORDNO (data);
 355 
 356   // If C(PPR.PRR) = 0 then C(SDW.P) -> C(PPR.P);
 357   //     otherwise 0 -> C(PPR.P)
 358   // Done at M
 359 
 360 //KL:
 361   DBGAPP ("doAppendCycleRTCDOperandFetch(KL)\n");
 362 
 363   // C(TPR.TSR) -> C(PPR.PSR)
 364   cpu.PPR.PSR = cpu.TPR.TSR;
 365   // C(TPR.CA) -> C(PPR.IC)
 366   cpu.PPR.IC = cpu.TPR.CA;
 367 
 368   goto M;
 369 
 370 M: // Set P
 371   DBGAPP ("doAppendCycleRTCDOperandFetch(M)\n");
 372 
 373   // C(TPR.TRR) = 0?
 374   if (cpu.TPR.TRR == 0) {
 375     // C(SDW.P) -> C(PPR.P)
 376     cpu.PPR.P = cpu.SDW->P;
 377   } else {
 378     // 0 C(PPR.P)
 379     cpu.PPR.P = 0;
 380   }
 381 
 382 //Exit:;
 383 
 384   PNL (cpu.APUDataBusOffset = cpu.TPR.CA;)
 385   PNL (cpu.APUDataBusAddr = finalAddress;)
 386 
 387   PNL (L68_ (cpu.apu.state |= apu_FA;))
 388 
 389   DBGAPP ("doAppendCycleRTCDOperandFetch (Exit) PRR %o PSR %05o P %o IC %06o\n",
 390           cpu.PPR.PRR, cpu.PPR.PSR, cpu.PPR.P, cpu.PPR.IC);
 391   DBGAPP ("doAppendCycleRTCDOperandFetch (Exit) TRR %o TSR %05o TBR %02o CA %06o\n",
 392           cpu.TPR.TRR, cpu.TPR.TSR, cpu.TPR.TBR, cpu.TPR.CA);
 393 
 394   return finalAddress;
 395 }

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