root/src/dps8/doAppendCycleAPUDataStore.h

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

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. doAppendCycleAPUDataStore

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

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