root/src/dps8/doAppendCycleABSA.h

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

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. doAppendCycleABSA

   1 /*
   2  * vim: filetype=c:tabstop=4:ai:expandtab
   3  * SPDX-License-Identifier: ICU
   4  * scspell-id: b05ae630-171d-11ee-b5d9-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 #undef thisCycle
  19 #define thisCycle ABSA_CYCLE
  20 word24 doAppendCycleABSA (cpu_state_t * cpup, word36 * data, uint nWords) {
     /* [previous][next][first][last][top][bottom][index][help] */
  21   DCDstruct * i = & cpu.currentInstruction;
  22   DBGAPP ("doAppendCycleABSA(Entry) thisCycle=ABSA_CYCLE\n");
  23   DBGAPP ("doAppendCycleABSA(Entry) lastCycle=%s\n", str_pct (cpu.apu.lastCycle));
  24   DBGAPP ("doAppendCycleABSA(Entry) CA %06o\n", cpu.TPR.CA);
  25   DBGAPP ("doAppendCycleABSA(Entry) n=%2u\n", nWords);
  26   DBGAPP ("doAppendCycleABSA(Entry) PPR.PRR=%o PPR.PSR=%05o\n", cpu.PPR.PRR, cpu.PPR.PSR);
  27   DBGAPP ("doAppendCycleABSA(Entry) TPR.TRR=%o TPR.TSR=%05o\n", cpu.TPR.TRR, cpu.TPR.TSR);
  28 
  29   if (i->b29) {
  30     DBGAPP ("doAppendCycleABSA(Entry) isb29 PRNO %o\n", GET_PRN (IWB_IRODD));
  31   }
  32 
  33   bool nomatch = true;
  34   if (cpu.tweaks.enable_wam) {
  35     // AL39: The associative memory is ignored (forced to "no match") during
  36     // address preparation.
  37     // lptp,lptr,lsdp,lsdr,sptp,sptr,ssdp,ssdr
  38     // Unfortunately, ISOLTS doesn't try to execute any of these in append mode.
  39     // XXX should this be only for OPERAND_READ and OPERAND_STORE?
  40     nomatch = ((i->opcode == 0232 || i->opcode == 0254 ||
  41                 i->opcode == 0154 || i->opcode == 0173) &&
  42                 i->opcodeX ) ||
  43               ((i->opcode == 0557 || i->opcode == 0257) &&
  44                 ! i->opcodeX);
  45   }
  46 
  47   processor_cycle_type lastCycle = cpu.apu.lastCycle;
  48   cpu.apu.lastCycle = ABSA_CYCLE;
  49 
  50   DBGAPP ("doAppendCycleABSA(Entry) XSF %o\n", cpu.cu.XSF);
  51 
  52   PNL (L68_ (cpu.apu.state = 0;))
  53 
  54   cpu.RSDWH_R1 = 0;
  55 
  56   cpu.acvFaults = 0;
  57 
  58 //#define FMSG(x) x
  59 #define FMSG(x)
  60   FMSG (char * acvFaultsMsg = "<unknown>";)
  61 
  62   word24 finalAddress = (word24) -1;  // not everything requires a final
  63                                       // address
  64 
  65 //
  66 //  A:
  67 //    Get SDW
  68 
  69   PNL (cpu.APUMemAddr = cpu.TPR.CA;)
  70 
  71   DBGAPP ("doAppendCycleABSA(A)\n");
  72 
  73   // is SDW for C(TPR.TSR) in SDWAM?
  74   if (nomatch || ! fetch_sdw_from_sdwam (cpup, cpu.TPR.TSR)) {
  75     // No
  76     DBGAPP ("doAppendCycleABSA(A):SDW for segment %05o not in SDWAM\n", cpu.TPR.TSR);
  77 
  78     DBGAPP ("doAppendCycleABSA(A):DSBR.U=%o\n", cpu.DSBR.U);
  79 
  80     if (cpu.DSBR.U == 0) {
  81       fetch_dsptw (cpup, cpu.TPR.TSR);
  82 
  83       if (! cpu.PTW0.DF)
  84         doFault (FAULT_DF0 + cpu.PTW0.FC, fst_zero, "doAppendCycleABSA(A): PTW0.F == 0");
  85 
  86       if (! cpu.PTW0.U)
  87         modify_dsptw (cpup, cpu.TPR.TSR);
  88 
  89       fetch_psdw (cpup, cpu.TPR.TSR);
  90     } else
  91       fetch_nsdw (cpup, cpu.TPR.TSR); // load SDW0 from descriptor segment table.
  92 
  93     // load SDWAM .....
  94     load_sdwam (cpup, cpu.TPR.TSR, nomatch);
  95   }
  96   DBGAPP ("doAppendCycleABSA(A) R1 %o R2 %o R3 %o E %o\n", cpu.SDW->R1, cpu.SDW->R2, cpu.SDW->R3, cpu.SDW->E);
  97 
  98   // Yes...
  99   cpu.RSDWH_R1 = cpu.SDW->R1;
 100 
 101 ////////////////////////////////////////
 102 //
 103 // Sheet 3: "B"
 104 //
 105 ////////////////////////////////////////
 106 
 107 //
 108 // B: Check the ring
 109 //
 110 
 111   DBGAPP ("doAppendCycleABSA(B)\n");
 112 
 113   // check ring bracket consistency
 114 
 115   //C(SDW.R1) <= C(SDW.R2) <= C(SDW .R3)?
 116   if (! (cpu.SDW->R1 <= cpu.SDW->R2 && cpu.SDW->R2 <= cpu.SDW->R3)) {
 117     // Set fault ACV0 = IRO
 118     cpu.acvFaults |= ACV0;
 119     PNL (L68_ (cpu.apu.state |= apu_FLT;))
 120     FMSG (acvFaultsMsg = "acvFaults(B) C(SDW.R1) <= C(SDW.R2) <= " "C(SDW .R3)";)
 121   }
 122 
 123   // lastCycle == RTCD_OPERAND_FETCH
 124   // if a fault happens between the RTCD_OPERAND_FETCH and the INSTRUCTION_FETCH
 125   // of the next instruction - this happens about 35 time for just booting  and
 126   // shutting down multics -- a stored lastCycle is useless.
 127   // the opcode is preserved across faults and only replaced as the
 128   // INSTRUCTION_FETCH succeeds.
 129   if (lastCycle == RTCD_OPERAND_FETCH)
 130     sim_warn ("%s: lastCycle == RTCD_OPERAND_FETCH opcode %0#o\n", __func__, i->opcode);
 131 
 132   //
 133   // check read bracket for read access
 134   //
 135 
 136   DBGAPP ("doAppendCycleABSA(B):!STR-OP\n");
 137 
 138   // No
 139   // C(TPR.TRR) > C(SDW .R2)?
 140   if (cpu.TPR.TRR > cpu.SDW->R2) {
 141     DBGAPP ("ACV3\n");
 142     DBGAPP ("doAppendCycleABSA(B) ACV3\n");
 143     //Set fault ACV3 = ORB
 144     cpu.acvFaults |= ACV3;
 145     PNL (L68_ (cpu.apu.state |= apu_FLT;))
 146     FMSG (acvFaultsMsg = "acvFaults(B) C(TPR.TRR) > C(SDW .R2)";)
 147   }
 148 
 149   if (cpu.SDW->R == 0) {
 150     // isolts 870
 151     cpu.TPR.TRR = cpu.PPR.PRR;
 152 
 153     //C(PPR.PSR) = C(TPR.TSR)?
 154     if (cpu.PPR.PSR != cpu.TPR.TSR) {
 155       DBGAPP ("ACV4\n");
 156       DBGAPP ("doAppendCycleABSA(B) ACV4\n");
 157       //Set fault ACV4 = R-OFF
 158       cpu.acvFaults |= ACV4;
 159       PNL (L68_ (cpu.apu.state |= apu_FLT;))
 160       FMSG (acvFaultsMsg = "acvFaults(B) C(PPR.PSR) = C(TPR.TSR)";)
 161     //} else {
 162       // sim_warn ("doAppendCycleABSA(B) SDW->R == 0 && cpu.PPR.PSR == cpu.TPR.TSR: %0#o\n", cpu.PPR.PSR);
 163     }
 164   }
 165 
 166 ////////////////////////////////////////
 167 //
 168 // Sheet 7: "G"
 169 //
 170 ////////////////////////////////////////
 171 
 172   DBGAPP ("doAppendCycleABSA(G)\n");
 173 
 174   //C(TPR.CA)0,13 > SDW.BOUND?
 175   if (((cpu.TPR.CA >> 4) & 037777) > cpu.SDW->BOUND) {
 176     DBGAPP ("ACV15\n");
 177     DBGAPP ("doAppendCycleABSA(G) ACV15\n");
 178     cpu.acvFaults |= ACV15;
 179     PNL (L68_ (cpu.apu.state |= apu_FLT;))
 180     FMSG (acvFaultsMsg = "acvFaults(G) C(TPR.CA)0,13 > SDW.BOUND";)
 181     DBGAPP ("acvFaults(G) C(TPR.CA)0,13 > SDW.BOUND\n"
 182             "   CA %06o CA>>4 & 037777 %06o SDW->BOUND %06o",
 183             cpu.TPR.CA, ((cpu.TPR.CA >> 4) & 037777), cpu.SDW->BOUND);
 184   }
 185 
 186   if (cpu.acvFaults) {
 187     DBGAPP ("doAppendCycleABSA(G) acvFaults\n");
 188     PNL (L68_ (cpu.apu.state |= apu_FLT;))
 189     // Initiate an access violation fault
 190     doFault (FAULT_ACV, (_fault_subtype) {.fault_acv_subtype=cpu.acvFaults}, "ACV fault");
 191   }
 192 
 193   // is segment C(TPR.TSR) paged?
 194   if (cpu.SDW->U)
 195     goto H; // Not paged
 196 
 197   // Yes. segment is paged ...
 198   // is PTW for C(TPR.CA) in PTWAM?
 199 
 200   DBGAPP ("doAppendCycleABSA(G) CA %06o\n", cpu.TPR.CA);
 201   if (nomatch || ! fetch_ptw_from_ptwam (cpup, cpu.SDW->POINTER, cpu.TPR.CA)) { //TPR.CA))
 202     fetch_ptw (cpup, cpu.SDW, cpu.TPR.CA);
 203     loadPTWAM (cpup, cpu.SDW->POINTER, cpu.TPR.CA, nomatch); // load PTW0 to PTWAM
 204   }
 205 
 206   // Prepage mode?
 207   // check for "uninterruptible" EIS instruction
 208   // ISOLTS-878 02: mvn,cmpn,mvne,ad3d; obviously also
 209   // ad2/3d,sb2/3d,mp2/3d,dv2/3d
 210   // DH03 p.8-13: probably also mve,btd,dtb
 211   if (i->opcodeX && ((i->opcode & 0770)== 0200|| (i->opcode & 0770) == 0220 || \
 212                      (i->opcode & 0770)== 020 || (i->opcode & 0770) == 0300)) {
 213     do_ptw2 (cpup, cpu.SDW, cpu.TPR.CA);
 214   }
 215   goto I;
 216 
 217 ////////////////////////////////////////
 218 //
 219 // Sheet 8: "H", "I"
 220 //
 221 ////////////////////////////////////////
 222 
 223 H:;
 224   DBGAPP ("doAppendCycleABSA(H): FANP\n");
 225 
 226   PNL (L68_ (cpu.apu.state |= apu_FANP;))
 227 
 228 
 229 
 230 
 231 
 232 
 233 
 234   set_apu_status (cpup, apuStatus_FANP);
 235 
 236   DBGAPP ("doAppendCycleABSA(H): SDW->ADDR=%08o CA=%06o \n", cpu.SDW->ADDR, cpu.TPR.CA);
 237 
 238   finalAddress = (cpu.SDW->ADDR & 077777760) + cpu.TPR.CA;
 239   finalAddress &= 0xffffff;
 240   PNL (cpu.APUMemAddr = finalAddress;)
 241 
 242   DBGAPP ("doAppendCycleABSA(H:FANP): (%05o:%06o) finalAddress=%08o\n", cpu.TPR.TSR, cpu.TPR.CA, finalAddress);
 243 
 244   goto HI;
 245 
 246 I:;
 247 
 248   // final address paged
 249   set_apu_status (cpup, apuStatus_FAP);
 250   PNL (L68_ (cpu.apu.state |= apu_FAP;))
 251 
 252   word24 y2 = cpu.TPR.CA % 1024;
 253 
 254   // AL39: The hardware ignores low order bits of the main memory page
 255   // address according to page size
 256   finalAddress = (((word24)cpu.PTW->ADDR & 0777760) << 6) + y2;
 257   finalAddress &= 0xffffff;
 258   PNL (cpu.APUMemAddr = finalAddress;)
 259 
 260 #if defined(L68)
 261   if (cpu.MR_cache.emr && cpu.MR_cache.ihr)
 262     add_APU_history (APUH_FAP);
 263 #endif /* if defined(L68) */
 264   DBGAPP ("doAppendCycleABSA(H:FAP): (%05o:%06o) finalAddress=%08o\n", cpu.TPR.TSR, cpu.TPR.CA, finalAddress);
 265 
 266   goto HI;
 267 
 268 HI:
 269   DBGAPP ("doAppendCycleABSA(HI)\n");
 270 
 271   goto Exit;
 272 
 273 Exit:;
 274 
 275   PNL (cpu.APUDataBusOffset = cpu.TPR.CA;)
 276   PNL (cpu.APUDataBusAddr = finalAddress;)
 277 
 278   PNL (L68_ (cpu.apu.state |= apu_FA;))
 279 
 280   DBGAPP ("doAppendCycleABSA (Exit) PRR %o PSR %05o P %o IC %06o\n", cpu.PPR.PRR, cpu.PPR.PSR, cpu.PPR.P, cpu.PPR.IC);
 281   DBGAPP ("doAppendCycleABSA (Exit) TRR %o TSR %05o TBR %02o CA %06o\n", cpu.TPR.TRR, cpu.TPR.TSR, cpu.TPR.TBR, cpu.TPR.CA);
 282 
 283   return finalAddress;    // or 0 or -1???
 284 }

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