Separate loading/creation of segments, name search etc into reuseable functions,...
authorNick Downing <nick@ndcode.org>
Sat, 19 Oct 2019 07:53:53 +0000 (18:53 +1100)
committerNick Downing <nick@ndcode.org>
Sat, 19 Oct 2019 07:53:53 +0000 (18:53 +1100)
Makefile
dps8/dps8_addrmods.c
dps8/dps8_append.c
dps8/dps8_faults.c
multics_sim.c
pl1/stack_header.incl.pl1 [new file with mode: 0644]
pointer.c [new file with mode: 0644]
pointer.h [new file with mode: 0644]
stack_header.h [new file with mode: 0644]

index 5e47ec8..a9606ef 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -3,6 +3,7 @@ CFLAGS=-g -std=c99 -U__STRICT_ANSI__ -IdecNumber -Idps8 -D_GNU_SOURCE -DUSE_READ
 
 multics_sim: \
 multics_sim.o \
+pointer.o \
 definition_dcls.o \
 decNumber/decContext.o \
 decNumber/decDouble.o \
index 8bae7b7..3846e86 100644 (file)
@@ -577,6 +577,9 @@ startCA:;
 
         if (GET_TM (GET_TAG (cpu.itxPair[0])) == TM_IT)
           {
+ bool snap_link(void); // in multics_sim.c
+ if (GET_TD (GET_TAG (cpu.itxPair[0])) == IT_F2 && snap_link())
+  ReadIndirect();
             if (GET_TD (GET_TAG (cpu.itxPair[0])) == IT_F2)
               {
                 doFault (FAULT_F2, fst_zero, "RI_MOD: IT_F2 (0)");
index dbb6294..fb3a899 100644 (file)
@@ -1328,585 +1328,585 @@ word24 do_append_cycle (processor_cycle_type thisCycle, word36 * data,
        DBGAPP ("RTCD_OPERAND_FETCH ABSOLUTE mode set TSR %05o TRR %o\n", cpu.TPR.TSR, cpu.TPR.TRR);
       }
 
-    goto A;
-
-////////////////////////////////////////
+//    goto A;
 //
-// Sheet 2: "A"
+//////////////////////////////////////////
+////
+//// Sheet 2: "A"
+////
+//////////////////////////////////////////
 //
-////////////////////////////////////////
-
+////
+////  A:
+////    Get SDW
 //
-//  A:
-//    Get SDW
-
-A:;
-
-    //PNL (cpu.APUMemAddr = address;)
-    PNL (cpu.APUMemAddr = cpu.TPR.CA;)
-
-    DBGAPP ("do_append_cycle(A)\n");
-    
-#ifdef WAM
-    // is SDW for C(TPR.TSR) in SDWAM?
-    if (nomatch || ! fetch_sdw_from_sdwam (cpu.TPR.TSR))
-#endif
-      {
-        // No
-        DBGAPP ("do_append_cycle(A):SDW for segment %05o not in SDWAM\n",
-                 cpu.TPR.TSR);
-        
-        DBGAPP ("do_append_cycle(A):DSBR.U=%o\n",
-                cpu.DSBR.U);
-        
-        if (cpu.DSBR.U == 0)
-          {
-            fetch_dsptw (cpu.TPR.TSR);
-            
-            if (! cpu.PTW0.DF)
-              doFault (FAULT_DF0 + cpu.PTW0.FC, fst_zero,
-                       "do_append_cycle(A): PTW0.F == 0");
-            
-            if (! cpu.PTW0.U)
-              modify_dsptw (cpu.TPR.TSR);
-            
-            fetch_psdw (cpu.TPR.TSR);
-          }
-        else
-          fetch_nsdw (cpu.TPR.TSR); // load SDW0 from descriptor segment table.
-        
-        if (cpu.SDW0.DF == 0)
-          {
-            if (thisCycle != ABSA_CYCLE)
-              {
-                DBGAPP ("do_append_cycle(A): SDW0.F == 0! "
-                        "Initiating directed fault\n");
-                // initiate a directed fault ...
-                doFault (FAULT_DF0 + cpu.SDW0.FC, fst_zero, "SDW0.F == 0");
-              }
-          }
-        // load SDWAM .....
-        load_sdwam (cpu.TPR.TSR, nomatch);
-      }
-    DBGAPP ("do_append_cycle(A) R1 %o R2 %o R3 %o E %o\n",
-            cpu.SDW->R1, cpu.SDW->R2, cpu.SDW->R3, cpu.SDW->E);
-
-    // Yes...
-    cpu.RSDWH_R1 = cpu.SDW->R1;
-
-////////////////////////////////////////
+//A:;
 //
-// Sheet 3: "B"
+//    //PNL (cpu.APUMemAddr = address;)
+//    PNL (cpu.APUMemAddr = cpu.TPR.CA;)
 //
-////////////////////////////////////////
-
+//    DBGAPP ("do_append_cycle(A)\n");
+//    
+//#ifdef WAM
+//    // is SDW for C(TPR.TSR) in SDWAM?
+//    if (nomatch || ! fetch_sdw_from_sdwam (cpu.TPR.TSR))
+//#endif
+//      {
+//        // No
+//        DBGAPP ("do_append_cycle(A):SDW for segment %05o not in SDWAM\n",
+//                 cpu.TPR.TSR);
+//        
+//        DBGAPP ("do_append_cycle(A):DSBR.U=%o\n",
+//                cpu.DSBR.U);
+//        
+//        if (cpu.DSBR.U == 0)
+//          {
+//            fetch_dsptw (cpu.TPR.TSR);
+//            
+//            if (! cpu.PTW0.DF)
+//              doFault (FAULT_DF0 + cpu.PTW0.FC, fst_zero,
+//                       "do_append_cycle(A): PTW0.F == 0");
+//            
+//            if (! cpu.PTW0.U)
+//              modify_dsptw (cpu.TPR.TSR);
+//            
+//            fetch_psdw (cpu.TPR.TSR);
+//          }
+//        else
+//          fetch_nsdw (cpu.TPR.TSR); // load SDW0 from descriptor segment table.
+//        
+//        if (cpu.SDW0.DF == 0)
+//          {
+//            if (thisCycle != ABSA_CYCLE)
+//              {
+//                DBGAPP ("do_append_cycle(A): SDW0.F == 0! "
+//                        "Initiating directed fault\n");
+//                // initiate a directed fault ...
+//                doFault (FAULT_DF0 + cpu.SDW0.FC, fst_zero, "SDW0.F == 0");
+//              }
+//          }
+//        // load SDWAM .....
+//        load_sdwam (cpu.TPR.TSR, nomatch);
+//      }
+//    DBGAPP ("do_append_cycle(A) R1 %o R2 %o R3 %o E %o\n",
+//            cpu.SDW->R1, cpu.SDW->R2, cpu.SDW->R3, cpu.SDW->E);
 //
-// B: Check the ring
+//    // Yes...
+//    cpu.RSDWH_R1 = cpu.SDW->R1;
 //
-
-    DBGAPP ("do_append_cycle(B)\n");
-
-    // check ring bracket consistency
-    
-    //C(SDW.R1) <= C(SDW.R2) <= C(SDW .R3)?
-    if (! (cpu.SDW->R1 <= cpu.SDW->R2 && cpu.SDW->R2 <= cpu.SDW->R3))
-      {
-        // Set fault ACV0 = IRO
-        cpu.acvFaults |= ACV0;
-        PNL (L68_ (cpu.apu.state |= apu_FLT;))
-        FMSG (acvFaultsMsg = "acvFaults(B) C(SDW.R1) <= C(SDW.R2) <= "
-                              "C(SDW .R3)";)
-      }
-
-    // lastCycle == RTCD_OPERAND_FETCH
-    // if a fault happens between the RTCD_OPERAND_FETCH and the INSTRUCTION_FETCH
-    // of the next instruction - this happens about 35 time for just booting  and
-    // shutting down multics -- a stored lastCycle is useless.
-    // the opcode is preserved accross faults and only replaced as the
-    // INSTRUCTION_FETCH succeeds.
-    if (thisCycle == INSTRUCTION_FETCH &&
-       i->opcode == 0610  && ! i->opcodeX)
-      goto C;
-    else if (lastCycle == RTCD_OPERAND_FETCH)
-      sim_warn ("%s: lastCycle == RTCD_OPERAND_FETCH opcode %0#o\n", __func__, i->opcode);
-
-    //
-    // B1: The operand is one of: an instruction, data to be read or data to be
-    //     written
-    //
-
-    // Is OPCODE call6?
-    if (thisCycle == OPERAND_READ && (i->info->flags & CALL6_INS))
-      goto E;
-
-#if 0
-    // If the instruction is a transfer operand or we are doing an instruction
-    // fetch, the operand is destined to be executed. Verify that the operand
-    // is executable
-
-    // The flowchart trips up on the TSP PRn|foo,* for the INDIRECT_WORD_FETCH.
-    // Also, it transfers to F on RTCD PRn,n and E-OFFs; the operand is not in
-    // an executable segment, and should be treated as READ_OPERAND here.
-
-    bool boolA = (thisCycle == INSTRUCTION_FETCH ||
-                 ((i->info->flags & TRANSFER_INS) &&
-                  thisCycle != INDIRECT_WORD_FETCH &&
-                  thisCycle != RTCD_OPERAND_FETCH));
-    bool boolB = (thisCycle == INSTRUCTION_FETCH ||
-                 ((i->info->flags & TRANSFER_INS) &&
-                  thisCycle == OPERAND_READ));
-    if (boolA != boolB)
-      sim_warn ("do_append_cycle(B) boolA %d != boolB %d cycle %s insflag %d\n",
-               boolA, boolB, str_pct (thisCycle), i->info->flags & TRANSFER_INS);
-#endif
-
-    // Transfer or instruction fetch?
-    if (thisCycle == INSTRUCTION_FETCH ||
-       (thisCycle == OPERAND_READ && (i->info->flags & TRANSFER_INS)))
-      goto F;
-
-    //
-    // check read bracket for read access
-    //
-
-#ifdef LOCKLESS
-    if (!StrOp || thisCycle == OPERAND_RMW || thisCycle == APU_DATA_RMW)
-#else
-    if (!StrOp)
-#endif
-      {
-        DBGAPP ("do_append_cycle(B):!STR-OP\n");
-        
-        // No
-        // C(TPR.TRR) > C(SDW .R2)?
-        if (cpu.TPR.TRR > cpu.SDW->R2)
-          {
-            DBGAPP ("ACV3\n");
-            DBGAPP ("do_append_cycle(B) ACV3\n");
-            //Set fault ACV3 = ORB
-            cpu.acvFaults |= ACV3;
-            PNL (L68_ (cpu.apu.state |= apu_FLT;))
-            FMSG (acvFaultsMsg = "acvFaults(B) C(TPR.TRR) > C(SDW .R2)";)
-          }
-        
-        if (cpu.SDW->R == 0)
-          {
-           // isolts 870
-           cpu.TPR.TRR = cpu.PPR.PRR;
-
-            //C(PPR.PSR) = C(TPR.TSR)?
-            if (cpu.PPR.PSR != cpu.TPR.TSR)
-              {
-                DBGAPP ("ACV4\n");
-                DBGAPP ("do_append_cycle(B) ACV4\n");
-                //Set fault ACV4 = R-OFF
-                cpu.acvFaults |= ACV4;
-                PNL (L68_ (cpu.apu.state |= apu_FLT;))
-                FMSG (acvFaultsMsg = "acvFaults(B) C(PPR.PSR) = C(TPR.TSR)";)
-              }
-           else
-             {
-               // sim_warn ("do_append_cycle(B) SDW->R == 0 && cpu.PPR.PSR == cpu.TPR.TSR: %0#o\n", cpu.PPR.PSR);
-             }
-          }
-      }
-
-    //
-    // check write bracket for write access
-    //
-#ifdef LOCKLESS
-    if (StrOp || thisCycle == OPERAND_RMW || thisCycle == APU_DATA_RMW)
-#else
-    if (StrOp)
-#endif
-      {
-        DBGAPP ("do_append_cycle(B):STR-OP\n");
-
-       // isolts 870
-       if (cpu.TPR.TSR == cpu.PPR.PSR)
-           cpu.TPR.TRR = cpu.PPR.PRR;
-
-        // C(TPR.TRR) > C(SDW .R1)? Note typo in AL39, R2 should be R1
-        if (cpu.TPR.TRR > cpu.SDW->R1)
-          {
-            DBGAPP ("ACV5 TRR %o R1 %o\n",
-                    cpu.TPR.TRR, cpu.SDW->R1);
-            //Set fault ACV5 = OWB
-            cpu.acvFaults |= ACV5;
-            PNL (L68_ (cpu.apu.state |= apu_FLT;))
-            FMSG (acvFaultsMsg = "acvFaults(B) C(TPR.TRR) > C(SDW .R1)";)
-          }
-        
-        if (! cpu.SDW->W)
-          {
-           // isolts 870
-           cpu.TPR.TRR = cpu.PPR.PRR;
-
-            DBGAPP ("ACV6\n");
-            // Set fault ACV6 = W-OFF
-            cpu.acvFaults |= ACV6;
-            PNL (L68_ (cpu.apu.state |= apu_FLT;))
-            FMSG (acvFaultsMsg = "acvFaults(B) ACV6 = W-OFF";)
-          }
-        
-      }
-#ifdef LOCKLESS
-    if (StrOp || thisCycle == OPERAND_RMW || thisCycle == APU_DATA_RMW)
-#else
-    if (StrOp)
-#endif
-      {
-        DBGAPP ("do_append_cycle(B):STR-OP\n");
-        
-        // C(TPR.TRR) > C(SDW .R1)? Note typo in AL39, R2 should be R1
-        if (cpu.TPR.TRR > cpu.SDW->R1)
-          {
-            DBGAPP ("ACV5 TRR %o R1 %o\n",
-                    cpu.TPR.TRR, cpu.SDW->R1);
-            //Set fault ACV5 = OWB
-            cpu.acvFaults |= ACV5;
-            PNL (L68_ (cpu.apu.state |= apu_FLT;))
-            FMSG (acvFaultsMsg = "acvFaults(B) C(TPR.TRR) > C(SDW .R1)";)
-          }
-        
-        if (! cpu.SDW->W)
-          {
-            DBGAPP ("ACV6\n");
-            // Set fault ACV6 = W-OFF
-            cpu.acvFaults |= ACV6;
-            PNL (L68_ (cpu.apu.state |= apu_FLT;))
-            FMSG (acvFaultsMsg = "acvFaults(B) ACV6 = W-OFF";)
-          }
-        
-      }
-    goto G;
-    
-////////////////////////////////////////
+//////////////////////////////////////////
+////
+//// Sheet 3: "B"
+////
+//////////////////////////////////////////
 //
-// Sheet 4: "C" "D"
+////
+//// B: Check the ring
+////
 //
-////////////////////////////////////////
-
-C:;
-    DBGAPP ("do_append_cycle(C)\n");
-
-    //
-    // check ring bracket for instruction fetch after rtcd instruction
-    //
-    //   allow outbound transfers (cpu.TPR.TRR >= cpu.PPR.PRR)
-    //
-
-    // C(TPR.TRR) < C(SDW.R1)?
-    // C(TPR.TRR) > C(SDW.R2)?
-    if (cpu.TPR.TRR < cpu.SDW->R1 ||
-        cpu.TPR.TRR > cpu.SDW->R2)
-      {
-        DBGAPP ("ACV1 c\n");
-        DBGAPP ("acvFaults(C) ACV1 ! ( C(SDW .R1) %o <= C(TPR.TRR) %o <= C(SDW .R2) %o )\n",
-               cpu.SDW->R1, cpu.TPR.TRR, cpu.SDW->R2);
-        //Set fault ACV1 = OEB
-        cpu.acvFaults |= ACV1;
-        PNL (L68_ (cpu.apu.state |= apu_FLT;))
-        FMSG (acvFaultsMsg = "acvFaults(C) C(SDW.R1 > C(TPR.TRR) > C(SDW.R2)";)
-      }
-    // SDW.E set ON?
-    if (! cpu.SDW->E)
-      {
-        DBGAPP ("ACV2 a\n");
-        DBGAPP ("do_append_cycle(C) ACV2\n");
-        //Set fault ACV2 = E-OFF
-        cpu.acvFaults |= ACV2;
-        PNL (L68_ (cpu.apu.state |= apu_FLT;))
-        FMSG (acvFaultsMsg = "acvFaults(C) SDW.E";)
-      }
-    if (cpu.TPR.TRR > cpu.PPR.PRR)
-      sim_warn ("rtcd: outbound call cpu.TPR.TRR %d cpu.PPR.PRR %d\n",
-               cpu.TPR.TRR, cpu.PPR.PRR);
-    // C(TPR.TRR) >= C(PPR.PRR)
-    if (cpu.TPR.TRR < cpu.PPR.PRR)
-      {
-        DBGAPP ("ACV11\n");
-        DBGAPP ("do_append_cycle(C) ACV11\n");
-        //Set fault ACV11 = INRET
-        cpu.acvFaults |= ACV11;
-        PNL (L68_ (cpu.apu.state |= apu_FLT;))
-        FMSG (acvFaultsMsg = "acvFaults(C) TRR>=PRR";)
-      }
-
-D:;
-    DBGAPP ("do_append_cycle(D)\n");
-    
-    // transfer or instruction fetch
-
-    // check ring alarm to catch outbound transfers
-
-    if (cpu.rRALR == 0)
-        goto G;
-    
-    // C(PPR.PRR) < RALR?
-    if (! (cpu.PPR.PRR < cpu.rRALR))
-      {
-        DBGAPP ("ACV13\n");
-        DBGAPP ("acvFaults(D) C(PPR.PRR) %o < RALR %o\n", 
-                cpu.PPR.PRR, cpu.rRALR);
-        cpu.acvFaults |= ACV13;
-        PNL (L68_ (cpu.apu.state |= apu_FLT;))
-        FMSG (acvFaultsMsg = "acvFaults(D) C(PPR.PRR) < RALR";)
-      }
-    
-    goto G;
-    
-////////////////////////////////////////
+//    DBGAPP ("do_append_cycle(B)\n");
 //
-// Sheet 5: "E"
+//    // check ring bracket consistency
+//    
+//    //C(SDW.R1) <= C(SDW.R2) <= C(SDW .R3)?
+//    if (! (cpu.SDW->R1 <= cpu.SDW->R2 && cpu.SDW->R2 <= cpu.SDW->R3))
+//      {
+//        // Set fault ACV0 = IRO
+//        cpu.acvFaults |= ACV0;
+//        PNL (L68_ (cpu.apu.state |= apu_FLT;))
+//        FMSG (acvFaultsMsg = "acvFaults(B) C(SDW.R1) <= C(SDW.R2) <= "
+//                              "C(SDW .R3)";)
+//      }
 //
-////////////////////////////////////////
-
-E:;
-
-    //
-    // check ring bracket for instruction fetch after call6 instruction
-    //   (this is the call6 read operand)
-    //
-
-    DBGAPP ("do_append_cycle(E): CALL6\n");
-    DBGAPP ("do_append_cycle(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);
-
-    //SDW.E set ON?
-    if (! cpu.SDW->E)
-      {
-        DBGAPP ("ACV2 b\n");
-        DBGAPP ("do_append_cycle(E) ACV2\n");
-        // Set fault ACV2 = E-OFF
-        cpu.acvFaults |= ACV2;
-        PNL (L68_ (cpu.apu.state |= apu_FLT;))
-        FMSG (acvFaultsMsg = "acvFaults(E) SDW .E set OFF";)
-      }
-    
-    //SDW .G set ON?
-    if (cpu.SDW->G)
-      goto E1;
-    
-    // C(PPR.PSR) = C(TPR.TSR)?
-    if (cpu.PPR.PSR == cpu.TPR.TSR && ! TST_I_ABS)
-      goto E1;
-    
-    // XXX This doesn't seem right
-    // EB is word 15; masking address makes no sense; rather 0-extend EB
-    // Fixes ISOLTS 880-01
-    if (cpu.TPR.CA >= (word18) cpu.SDW->EB)
-      {
-        DBGAPP ("ACV7\n");
-        DBGAPP ("do_append_cycle(E) ACV7\n");
-        // Set fault ACV7 = NO GA
-        cpu.acvFaults |= ACV7;
-        PNL (L68_ (cpu.apu.state |= apu_FLT;))
-        FMSG (acvFaultsMsg = "acvFaults(E) TPR.CA4-17 >= SDW.CL";)
-      }
-    
-E1:
-    DBGAPP ("do_append_cycle(E1): CALL6 (cont'd)\n");
-
-    // C(TPR.TRR) > SDW.R3?
-    if (cpu.TPR.TRR > cpu.SDW->R3)
-      {
-        DBGAPP ("ACV8\n");
-        DBGAPP ("do_append_cycle(E) ACV8\n");
-        //Set fault ACV8 = OCB
-        cpu.acvFaults |= ACV8;
-        PNL (L68_ (cpu.apu.state |= apu_FLT;))
-        FMSG (acvFaultsMsg = "acvFaults(E1) C(TPR.TRR) > SDW.R3";)
-      }
-    
-    // C(TPR.TRR) < SDW.R1?
-    if (cpu.TPR.TRR < cpu.SDW->R1)
-      {
-        DBGAPP ("ACV9\n");
-        DBGAPP ("do_append_cycle(E) ACV9\n");
-        // Set fault ACV9 = OCALL
-        cpu.acvFaults |= ACV9;
-        PNL (L68_ (cpu.apu.state |= apu_FLT;))
-        FMSG (acvFaultsMsg = "acvFaults(E1) C(TPR.TRR) < SDW.R1";)
-      }
-    
-    
-    // C(TPR.TRR) > C(PPR.PRR)?
-    if (cpu.TPR.TRR > cpu.PPR.PRR)
-      {
-        // C(PPR.PRR) < SDW.R2?
-        if (cpu.PPR.PRR < cpu.SDW->R2)
-          {
-            DBGAPP ("ACV10\n");
-            DBGAPP ("do_append_cycle(E) ACV10\n");
-            // Set fault ACV10 = BOC
-            cpu.acvFaults |= ACV10;
-            PNL (L68_ (cpu.apu.state |= apu_FLT;))
-            FMSG (acvFaultsMsg = "acvFaults(E1) C(TPR.TRR) > C(PPR.PRR) && "
-                  "C(PPR.PRR) < SDW.R2";)
-          }
-      }
-
-    
-    DBGAPP ("do_append_cycle(E1): CALL6 TPR.TRR %o SDW->R2 %o\n",
-            cpu.TPR.TRR, cpu.SDW->R2);
-
-    // C(TPR.TRR) > SDW.R2?
-    if (cpu.TPR.TRR > cpu.SDW->R2)
-      {
-        // SDW.R2 -> C(TPR.TRR)
-        cpu.TPR.TRR = cpu.SDW->R2;
-      }
-
-    DBGAPP ("do_append_cycle(E1): CALL6 TPR.TRR %o\n", cpu.TPR.TRR);
-    
-    goto G;
-    
-////////////////////////////////////////
+//    // lastCycle == RTCD_OPERAND_FETCH
+//    // if a fault happens between the RTCD_OPERAND_FETCH and the INSTRUCTION_FETCH
+//    // of the next instruction - this happens about 35 time for just booting  and
+//    // shutting down multics -- a stored lastCycle is useless.
+//    // the opcode is preserved accross faults and only replaced as the
+//    // INSTRUCTION_FETCH succeeds.
+//    if (thisCycle == INSTRUCTION_FETCH &&
+//     i->opcode == 0610  && ! i->opcodeX)
+//      goto C;
+//    else if (lastCycle == RTCD_OPERAND_FETCH)
+//      sim_warn ("%s: lastCycle == RTCD_OPERAND_FETCH opcode %0#o\n", __func__, i->opcode);
 //
-// Sheet 6: "F"
+//    //
+//    // B1: The operand is one of: an instruction, data to be read or data to be
+//    //     written
+//    //
 //
-////////////////////////////////////////
-
-F:;
-    PNL (L68_ (cpu.apu.state |= apu_PIAU;))
-    DBGAPP ("do_append_cycle(F): transfer or instruction fetch\n");
-
-    //
-    // check ring bracket for instruction fetch
-    //
-
-    // C(TPR.TRR) < C(SDW .R1)?
-    // C(TPR.TRR) > C(SDW .R2)?
-    if (cpu.TPR.TRR < cpu.SDW->R1 ||
-       cpu.TPR.TRR > cpu.SDW->R2)
-      {
-        DBGAPP ("ACV1 a/b\n");
-        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);
-        cpu.acvFaults |= ACV1;
-        PNL (L68_ (cpu.apu.state |= apu_FLT;))
-        FMSG (acvFaultsMsg = "acvFaults(F) C(TPR.TRR) < C(SDW .R1)";)
-      }
-    // SDW .E set ON?
-    if (! cpu.SDW->E)
-      {
-        DBGAPP ("ACV2 c \n");
-        DBGAPP ("do_append_cycle(F) ACV2\n");
-        cpu.acvFaults |= ACV2;
-        PNL (L68_ (cpu.apu.state |= apu_FLT;))
-        FMSG (acvFaultsMsg = "acvFaults(F) SDW .E set OFF";)
-      }
-    
-    // C(PPR.PRR) = C(TPR.TRR)?
-    if (cpu.PPR.PRR != cpu.TPR.TRR)
-      {
-        DBGAPP ("ACV12\n");
-        DBGAPP ("do_append_cycle(F) ACV12\n");
-        //Set fault ACV12 = CRT
-        cpu.acvFaults |= ACV12;
-        PNL (L68_ (cpu.apu.state |= apu_FLT;))
-        FMSG (acvFaultsMsg = "acvFaults(F) C(PPR.PRR) != C(TPR.TRR)";)
-      }
-    
-    goto D;
-
-////////////////////////////////////////
+//    // Is OPCODE call6?
+//    if (thisCycle == OPERAND_READ && (i->info->flags & CALL6_INS))
+//      goto E;
 //
-// Sheet 7: "G"
+//#if 0
+//    // If the instruction is a transfer operand or we are doing an instruction
+//    // fetch, the operand is destined to be executed. Verify that the operand
+//    // is executable
 //
-////////////////////////////////////////
-
-G:;
-    
-    DBGAPP ("do_append_cycle(G)\n");
-    
-    //C(TPR.CA)0,13 > SDW.BOUND?
-    if (((cpu.TPR.CA >> 4) & 037777) > cpu.SDW->BOUND)
-      {
-        DBGAPP ("ACV15\n");
-        DBGAPP ("do_append_cycle(G) ACV15\n");
-        cpu.acvFaults |= ACV15;
-        PNL (L68_ (cpu.apu.state |= apu_FLT;))
-        FMSG (acvFaultsMsg = "acvFaults(G) C(TPR.CA)0,13 > SDW.BOUND";)
-        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);
-      }
-    
-    if (cpu.acvFaults)
-      {
-        DBGAPP ("do_append_cycle(G) acvFaults\n");
-        PNL (L68_ (cpu.apu.state |= apu_FLT;))
-        // Initiate an access violation fault
-        doFault (FAULT_ACV, (_fault_subtype) {.fault_acv_subtype=cpu.acvFaults},
-                 "ACV fault");
-      }
-
-    // is segment C(TPR.TSR) paged?
-    if (cpu.SDW->U)
-      goto H; // Not paged
-    
-    // Yes. segment is paged ...
-    // is PTW for C(TPR.CA) in PTWAM?
-    
-    DBGAPP ("do_append_cycle(G) CA %06o\n", cpu.TPR.CA);
-#ifdef WAM
-    if (nomatch ||
-        ! fetch_ptw_from_ptwam (cpu.SDW->POINTER, cpu.TPR.CA))  //TPR.CA))
-#endif
-      {
-        fetch_ptw (cpu.SDW, cpu.TPR.CA);
-        if (! cpu.PTW0.DF)
-          {
-            if (thisCycle != ABSA_CYCLE)
-              {
-                // initiate a directed fault
-                doFault (FAULT_DF0 + cpu.PTW0.FC, (_fault_subtype) {.bits=0},
-                         "PTW0.F == 0");
-              }
-          }
-        loadPTWAM (cpu.SDW->POINTER, cpu.TPR.CA, nomatch); // load PTW0 to PTWAM
-      }
-    
-    // Prepage mode?
-    // check for "uninterruptible" EIS instruction
-    // ISOLTS-878 02: mvn,cmpn,mvne,ad3d; obviously also
-    // ad2/3d,sb2/3d,mp2/3d,dv2/3d
-    // DH03 p.8-13: probably also mve,btd,dtb
-    if (i->opcodeX && ((i->opcode & 0770)== 0200|| (i->opcode & 0770) == 0220
-        || (i->opcode & 0770)== 020|| (i->opcode & 0770) == 0300))
-      {
-        do_ptw2 (cpu.SDW, cpu.TPR.CA);
-      } 
-    goto I;
-    
-////////////////////////////////////////
+//    // The flowchart trips up on the TSP PRn|foo,* for the INDIRECT_WORD_FETCH.
+//    // Also, it transfers to F on RTCD PRn,n and E-OFFs; the operand is not in
+//    // an executable segment, and should be treated as READ_OPERAND here.
 //
-// Sheet 8: "H", "I"
+//    bool boolA = (thisCycle == INSTRUCTION_FETCH ||
+//               ((i->info->flags & TRANSFER_INS) &&
+//                thisCycle != INDIRECT_WORD_FETCH &&
+//                thisCycle != RTCD_OPERAND_FETCH));
+//    bool boolB = (thisCycle == INSTRUCTION_FETCH ||
+//               ((i->info->flags & TRANSFER_INS) &&
+//                thisCycle == OPERAND_READ));
+//    if (boolA != boolB)
+//      sim_warn ("do_append_cycle(B) boolA %d != boolB %d cycle %s insflag %d\n",
+//             boolA, boolB, str_pct (thisCycle), i->info->flags & TRANSFER_INS);
+//#endif
 //
-////////////////////////////////////////
-
-H:;
-    DBGAPP ("do_append_cycle(H): FANP\n");
-
-    PNL (L68_ (cpu.apu.state |= apu_FANP;))
-#if 0
-    // ISOLTS pa865 test-01a 101232
-    if (get_bar_mode ())
-      {
-        set_apu_status (apuStatus_FABS);
-      }
-    else
-      ....
-#endif
-    set_apu_status (apuStatus_FANP);
-
-    DBGAPP ("do_append_cycle(H): SDW->ADDR=%08o CA=%06o \n",
-            cpu.SDW->ADDR, cpu.TPR.CA);
+//    // Transfer or instruction fetch?
+//    if (thisCycle == INSTRUCTION_FETCH ||
+//     (thisCycle == OPERAND_READ && (i->info->flags & TRANSFER_INS)))
+//      goto F;
+//
+//    //
+//    // check read bracket for read access
+//    //
+//
+//#ifdef LOCKLESS
+//    if (!StrOp || thisCycle == OPERAND_RMW || thisCycle == APU_DATA_RMW)
+//#else
+//    if (!StrOp)
+//#endif
+//      {
+//        DBGAPP ("do_append_cycle(B):!STR-OP\n");
+//        
+//        // No
+//        // C(TPR.TRR) > C(SDW .R2)?
+//        if (cpu.TPR.TRR > cpu.SDW->R2)
+//          {
+//            DBGAPP ("ACV3\n");
+//            DBGAPP ("do_append_cycle(B) ACV3\n");
+//            //Set fault ACV3 = ORB
+//            cpu.acvFaults |= ACV3;
+//            PNL (L68_ (cpu.apu.state |= apu_FLT;))
+//            FMSG (acvFaultsMsg = "acvFaults(B) C(TPR.TRR) > C(SDW .R2)";)
+//          }
+//        
+//        if (cpu.SDW->R == 0)
+//          {
+//         // isolts 870
+//         cpu.TPR.TRR = cpu.PPR.PRR;
+//
+//            //C(PPR.PSR) = C(TPR.TSR)?
+//            if (cpu.PPR.PSR != cpu.TPR.TSR)
+//              {
+//                DBGAPP ("ACV4\n");
+//                DBGAPP ("do_append_cycle(B) ACV4\n");
+//                //Set fault ACV4 = R-OFF
+//                cpu.acvFaults |= ACV4;
+//                PNL (L68_ (cpu.apu.state |= apu_FLT;))
+//                FMSG (acvFaultsMsg = "acvFaults(B) C(PPR.PSR) = C(TPR.TSR)";)
+//              }
+//         else
+//           {
+//             // sim_warn ("do_append_cycle(B) SDW->R == 0 && cpu.PPR.PSR == cpu.TPR.TSR: %0#o\n", cpu.PPR.PSR);
+//           }
+//          }
+//      }
+//
+//    //
+//    // check write bracket for write access
+//    //
+//#ifdef LOCKLESS
+//    if (StrOp || thisCycle == OPERAND_RMW || thisCycle == APU_DATA_RMW)
+//#else
+//    if (StrOp)
+//#endif
+//      {
+//        DBGAPP ("do_append_cycle(B):STR-OP\n");
+//
+//     // isolts 870
+//     if (cpu.TPR.TSR == cpu.PPR.PSR)
+//         cpu.TPR.TRR = cpu.PPR.PRR;
+//
+//        // C(TPR.TRR) > C(SDW .R1)? Note typo in AL39, R2 should be R1
+//        if (cpu.TPR.TRR > cpu.SDW->R1)
+//          {
+//            DBGAPP ("ACV5 TRR %o R1 %o\n",
+//                    cpu.TPR.TRR, cpu.SDW->R1);
+//            //Set fault ACV5 = OWB
+//            cpu.acvFaults |= ACV5;
+//            PNL (L68_ (cpu.apu.state |= apu_FLT;))
+//            FMSG (acvFaultsMsg = "acvFaults(B) C(TPR.TRR) > C(SDW .R1)";)
+//          }
+//        
+//        if (! cpu.SDW->W)
+//          {
+//         // isolts 870
+//         cpu.TPR.TRR = cpu.PPR.PRR;
+//
+//            DBGAPP ("ACV6\n");
+//            // Set fault ACV6 = W-OFF
+//            cpu.acvFaults |= ACV6;
+//            PNL (L68_ (cpu.apu.state |= apu_FLT;))
+//            FMSG (acvFaultsMsg = "acvFaults(B) ACV6 = W-OFF";)
+//          }
+//        
+//      }
+//#ifdef LOCKLESS
+//    if (StrOp || thisCycle == OPERAND_RMW || thisCycle == APU_DATA_RMW)
+//#else
+//    if (StrOp)
+//#endif
+//      {
+//        DBGAPP ("do_append_cycle(B):STR-OP\n");
+//        
+//        // C(TPR.TRR) > C(SDW .R1)? Note typo in AL39, R2 should be R1
+//        if (cpu.TPR.TRR > cpu.SDW->R1)
+//          {
+//            DBGAPP ("ACV5 TRR %o R1 %o\n",
+//                    cpu.TPR.TRR, cpu.SDW->R1);
+//            //Set fault ACV5 = OWB
+//            cpu.acvFaults |= ACV5;
+//            PNL (L68_ (cpu.apu.state |= apu_FLT;))
+//            FMSG (acvFaultsMsg = "acvFaults(B) C(TPR.TRR) > C(SDW .R1)";)
+//          }
+//        
+//        if (! cpu.SDW->W)
+//          {
+//            DBGAPP ("ACV6\n");
+//            // Set fault ACV6 = W-OFF
+//            cpu.acvFaults |= ACV6;
+//            PNL (L68_ (cpu.apu.state |= apu_FLT;))
+//            FMSG (acvFaultsMsg = "acvFaults(B) ACV6 = W-OFF";)
+//          }
+//        
+//      }
+//    goto G;
+//    
+//////////////////////////////////////////
+////
+//// Sheet 4: "C" "D"
+////
+//////////////////////////////////////////
+//
+//C:;
+//    DBGAPP ("do_append_cycle(C)\n");
+//
+//    //
+//    // check ring bracket for instruction fetch after rtcd instruction
+//    //
+//    //   allow outbound transfers (cpu.TPR.TRR >= cpu.PPR.PRR)
+//    //
+//
+//    // C(TPR.TRR) < C(SDW.R1)?
+//    // C(TPR.TRR) > C(SDW.R2)?
+//    if (cpu.TPR.TRR < cpu.SDW->R1 ||
+//        cpu.TPR.TRR > cpu.SDW->R2)
+//      {
+//        DBGAPP ("ACV1 c\n");
+//        DBGAPP ("acvFaults(C) ACV1 ! ( C(SDW .R1) %o <= C(TPR.TRR) %o <= C(SDW .R2) %o )\n",
+//             cpu.SDW->R1, cpu.TPR.TRR, cpu.SDW->R2);
+//        //Set fault ACV1 = OEB
+//        cpu.acvFaults |= ACV1;
+//        PNL (L68_ (cpu.apu.state |= apu_FLT;))
+//        FMSG (acvFaultsMsg = "acvFaults(C) C(SDW.R1 > C(TPR.TRR) > C(SDW.R2)";)
+//      }
+//    // SDW.E set ON?
+//    if (! cpu.SDW->E)
+//      {
+//        DBGAPP ("ACV2 a\n");
+//        DBGAPP ("do_append_cycle(C) ACV2\n");
+//        //Set fault ACV2 = E-OFF
+//        cpu.acvFaults |= ACV2;
+//        PNL (L68_ (cpu.apu.state |= apu_FLT;))
+//        FMSG (acvFaultsMsg = "acvFaults(C) SDW.E";)
+//      }
+//    if (cpu.TPR.TRR > cpu.PPR.PRR)
+//      sim_warn ("rtcd: outbound call cpu.TPR.TRR %d cpu.PPR.PRR %d\n",
+//             cpu.TPR.TRR, cpu.PPR.PRR);
+//    // C(TPR.TRR) >= C(PPR.PRR)
+//    if (cpu.TPR.TRR < cpu.PPR.PRR)
+//      {
+//        DBGAPP ("ACV11\n");
+//        DBGAPP ("do_append_cycle(C) ACV11\n");
+//        //Set fault ACV11 = INRET
+//        cpu.acvFaults |= ACV11;
+//        PNL (L68_ (cpu.apu.state |= apu_FLT;))
+//        FMSG (acvFaultsMsg = "acvFaults(C) TRR>=PRR";)
+//      }
+//
+//D:;
+//    DBGAPP ("do_append_cycle(D)\n");
+//    
+//    // transfer or instruction fetch
+//
+//    // check ring alarm to catch outbound transfers
+//
+//    if (cpu.rRALR == 0)
+//        goto G;
+//    
+//    // C(PPR.PRR) < RALR?
+//    if (! (cpu.PPR.PRR < cpu.rRALR))
+//      {
+//        DBGAPP ("ACV13\n");
+//        DBGAPP ("acvFaults(D) C(PPR.PRR) %o < RALR %o\n", 
+//                cpu.PPR.PRR, cpu.rRALR);
+//        cpu.acvFaults |= ACV13;
+//        PNL (L68_ (cpu.apu.state |= apu_FLT;))
+//        FMSG (acvFaultsMsg = "acvFaults(D) C(PPR.PRR) < RALR";)
+//      }
+//    
+//    goto G;
+//    
+//////////////////////////////////////////
+////
+//// Sheet 5: "E"
+////
+//////////////////////////////////////////
+//
+//E:;
+//
+//    //
+//    // check ring bracket for instruction fetch after call6 instruction
+//    //   (this is the call6 read operand)
+//    //
+//
+//    DBGAPP ("do_append_cycle(E): CALL6\n");
+//    DBGAPP ("do_append_cycle(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);
+//
+//    //SDW.E set ON?
+//    if (! cpu.SDW->E)
+//      {
+//        DBGAPP ("ACV2 b\n");
+//        DBGAPP ("do_append_cycle(E) ACV2\n");
+//        // Set fault ACV2 = E-OFF
+//        cpu.acvFaults |= ACV2;
+//        PNL (L68_ (cpu.apu.state |= apu_FLT;))
+//        FMSG (acvFaultsMsg = "acvFaults(E) SDW .E set OFF";)
+//      }
+//    
+//    //SDW .G set ON?
+//    if (cpu.SDW->G)
+//      goto E1;
+//    
+//    // C(PPR.PSR) = C(TPR.TSR)?
+//    if (cpu.PPR.PSR == cpu.TPR.TSR && ! TST_I_ABS)
+//      goto E1;
+//    
+//    // XXX This doesn't seem right
+//    // EB is word 15; masking address makes no sense; rather 0-extend EB
+//    // Fixes ISOLTS 880-01
+//    if (cpu.TPR.CA >= (word18) cpu.SDW->EB)
+//      {
+//        DBGAPP ("ACV7\n");
+//        DBGAPP ("do_append_cycle(E) ACV7\n");
+//        // Set fault ACV7 = NO GA
+//        cpu.acvFaults |= ACV7;
+//        PNL (L68_ (cpu.apu.state |= apu_FLT;))
+//        FMSG (acvFaultsMsg = "acvFaults(E) TPR.CA4-17 >= SDW.CL";)
+//      }
+//    
+//E1:
+//    DBGAPP ("do_append_cycle(E1): CALL6 (cont'd)\n");
+//
+//    // C(TPR.TRR) > SDW.R3?
+//    if (cpu.TPR.TRR > cpu.SDW->R3)
+//      {
+//        DBGAPP ("ACV8\n");
+//        DBGAPP ("do_append_cycle(E) ACV8\n");
+//        //Set fault ACV8 = OCB
+//        cpu.acvFaults |= ACV8;
+//        PNL (L68_ (cpu.apu.state |= apu_FLT;))
+//        FMSG (acvFaultsMsg = "acvFaults(E1) C(TPR.TRR) > SDW.R3";)
+//      }
+//    
+//    // C(TPR.TRR) < SDW.R1?
+//    if (cpu.TPR.TRR < cpu.SDW->R1)
+//      {
+//        DBGAPP ("ACV9\n");
+//        DBGAPP ("do_append_cycle(E) ACV9\n");
+//        // Set fault ACV9 = OCALL
+//        cpu.acvFaults |= ACV9;
+//        PNL (L68_ (cpu.apu.state |= apu_FLT;))
+//        FMSG (acvFaultsMsg = "acvFaults(E1) C(TPR.TRR) < SDW.R1";)
+//      }
+//    
+//    
+//    // C(TPR.TRR) > C(PPR.PRR)?
+//    if (cpu.TPR.TRR > cpu.PPR.PRR)
+//      {
+//        // C(PPR.PRR) < SDW.R2?
+//        if (cpu.PPR.PRR < cpu.SDW->R2)
+//          {
+//            DBGAPP ("ACV10\n");
+//            DBGAPP ("do_append_cycle(E) ACV10\n");
+//            // Set fault ACV10 = BOC
+//            cpu.acvFaults |= ACV10;
+//            PNL (L68_ (cpu.apu.state |= apu_FLT;))
+//            FMSG (acvFaultsMsg = "acvFaults(E1) C(TPR.TRR) > C(PPR.PRR) && "
+//                  "C(PPR.PRR) < SDW.R2";)
+//          }
+//      }
+//
+//    
+//    DBGAPP ("do_append_cycle(E1): CALL6 TPR.TRR %o SDW->R2 %o\n",
+//            cpu.TPR.TRR, cpu.SDW->R2);
+//
+//    // C(TPR.TRR) > SDW.R2?
+//    if (cpu.TPR.TRR > cpu.SDW->R2)
+//      {
+//        // SDW.R2 -> C(TPR.TRR)
+//        cpu.TPR.TRR = cpu.SDW->R2;
+//      }
+//
+//    DBGAPP ("do_append_cycle(E1): CALL6 TPR.TRR %o\n", cpu.TPR.TRR);
+//    
+//    goto G;
+//    
+//////////////////////////////////////////
+////
+//// Sheet 6: "F"
+////
+//////////////////////////////////////////
+//
+//F:;
+//    PNL (L68_ (cpu.apu.state |= apu_PIAU;))
+//    DBGAPP ("do_append_cycle(F): transfer or instruction fetch\n");
+//
+//    //
+//    // check ring bracket for instruction fetch
+//    //
+//
+//    // C(TPR.TRR) < C(SDW .R1)?
+//    // C(TPR.TRR) > C(SDW .R2)?
+//    if (cpu.TPR.TRR < cpu.SDW->R1 ||
+//     cpu.TPR.TRR > cpu.SDW->R2)
+//      {
+//        DBGAPP ("ACV1 a/b\n");
+//        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);
+//        cpu.acvFaults |= ACV1;
+//        PNL (L68_ (cpu.apu.state |= apu_FLT;))
+//        FMSG (acvFaultsMsg = "acvFaults(F) C(TPR.TRR) < C(SDW .R1)";)
+//      }
+//    // SDW .E set ON?
+//    if (! cpu.SDW->E)
+//      {
+//        DBGAPP ("ACV2 c \n");
+//        DBGAPP ("do_append_cycle(F) ACV2\n");
+//        cpu.acvFaults |= ACV2;
+//        PNL (L68_ (cpu.apu.state |= apu_FLT;))
+//        FMSG (acvFaultsMsg = "acvFaults(F) SDW .E set OFF";)
+//      }
+//    
+//    // C(PPR.PRR) = C(TPR.TRR)?
+//    if (cpu.PPR.PRR != cpu.TPR.TRR)
+//      {
+//        DBGAPP ("ACV12\n");
+//        DBGAPP ("do_append_cycle(F) ACV12\n");
+//        //Set fault ACV12 = CRT
+//        cpu.acvFaults |= ACV12;
+//        PNL (L68_ (cpu.apu.state |= apu_FLT;))
+//        FMSG (acvFaultsMsg = "acvFaults(F) C(PPR.PRR) != C(TPR.TRR)";)
+//      }
+//    
+//    goto D;
+//
+//////////////////////////////////////////
+////
+//// Sheet 7: "G"
+////
+//////////////////////////////////////////
+//
+//G:;
+//    
+//    DBGAPP ("do_append_cycle(G)\n");
+//    
+//    //C(TPR.CA)0,13 > SDW.BOUND?
+//    if (((cpu.TPR.CA >> 4) & 037777) > cpu.SDW->BOUND)
+//      {
+//        DBGAPP ("ACV15\n");
+//        DBGAPP ("do_append_cycle(G) ACV15\n");
+//        cpu.acvFaults |= ACV15;
+//        PNL (L68_ (cpu.apu.state |= apu_FLT;))
+//        FMSG (acvFaultsMsg = "acvFaults(G) C(TPR.CA)0,13 > SDW.BOUND";)
+//        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);
+//      }
+//    
+//    if (cpu.acvFaults)
+//      {
+//        DBGAPP ("do_append_cycle(G) acvFaults\n");
+//        PNL (L68_ (cpu.apu.state |= apu_FLT;))
+//        // Initiate an access violation fault
+//        doFault (FAULT_ACV, (_fault_subtype) {.fault_acv_subtype=cpu.acvFaults},
+//                 "ACV fault");
+//      }
+//
+//    // is segment C(TPR.TSR) paged?
+//    if (cpu.SDW->U)
+//      goto H; // Not paged
+//    
+//    // Yes. segment is paged ...
+//    // is PTW for C(TPR.CA) in PTWAM?
+//    
+//    DBGAPP ("do_append_cycle(G) CA %06o\n", cpu.TPR.CA);
+//#ifdef WAM
+//    if (nomatch ||
+//        ! fetch_ptw_from_ptwam (cpu.SDW->POINTER, cpu.TPR.CA))  //TPR.CA))
+//#endif
+//      {
+//        fetch_ptw (cpu.SDW, cpu.TPR.CA);
+//        if (! cpu.PTW0.DF)
+//          {
+//            if (thisCycle != ABSA_CYCLE)
+//              {
+//                // initiate a directed fault
+//                doFault (FAULT_DF0 + cpu.PTW0.FC, (_fault_subtype) {.bits=0},
+//                         "PTW0.F == 0");
+//              }
+//          }
+//        loadPTWAM (cpu.SDW->POINTER, cpu.TPR.CA, nomatch); // load PTW0 to PTWAM
+//      }
+//    
+//    // Prepage mode?
+//    // check for "uninterruptible" EIS instruction
+//    // ISOLTS-878 02: mvn,cmpn,mvne,ad3d; obviously also
+//    // ad2/3d,sb2/3d,mp2/3d,dv2/3d
+//    // DH03 p.8-13: probably also mve,btd,dtb
+//    if (i->opcodeX && ((i->opcode & 0770)== 0200|| (i->opcode & 0770) == 0220
+//        || (i->opcode & 0770)== 020|| (i->opcode & 0770) == 0300))
+//      {
+//        do_ptw2 (cpu.SDW, cpu.TPR.CA);
+//      } 
+//    goto I;
+//    
+//////////////////////////////////////////
+////
+//// Sheet 8: "H", "I"
+////
+//////////////////////////////////////////
+//
+//H:;
+//    DBGAPP ("do_append_cycle(H): FANP\n");
+//
+//    PNL (L68_ (cpu.apu.state |= apu_FANP;))
+//#if 0
+//    // ISOLTS pa865 test-01a 101232
+//    if (get_bar_mode ())
+//      {
+//        set_apu_status (apuStatus_FABS);
+//      }
+//    else
+//      ....
+//#endif
+//    set_apu_status (apuStatus_FANP);
+//
+//    DBGAPP ("do_append_cycle(H): SDW->ADDR=%08o CA=%06o \n",
+//            cpu.SDW->ADDR, cpu.TPR.CA);
 
     if (thisCycle == RTCD_OPERAND_FETCH &&
         get_addr_mode () == ABSOLUTE_mode &&
@@ -1916,8 +1916,9 @@ H:;
       }
     else
       {
-        finalAddress = (cpu.SDW->ADDR & 077777760) + cpu.TPR.CA;
-        finalAddress &= 0xffffff;
+//        finalAddress = (cpu.SDW->ADDR & 077777760) + cpu.TPR.CA;
+//        finalAddress &= 0xffffff;
+ finalAddress = (cpu.TPR.TSR << 18) | cpu.TPR.CA;
       }
     PNL (cpu.APUMemAddr = finalAddress;)
     
index 5de1dbe..7295818 100644 (file)
@@ -378,6 +378,7 @@ else if (faultNumber == FAULT_ACV)
                "Fault %d(0%0o), sub %"PRIu64"(0%"PRIo64"), dfc %c, '%s'\n", 
                faultNumber, faultNumber, subFault.bits, subFault.bits, 
                cpu . bTroubleFaultCycle ? 'Y' : 'N', faultMsg);
+ abort();
 #ifdef HDBG
     hdbgFault (faultNumber, subFault, faultMsg);
 #endif
index e3dd289..520a3b2 100644 (file)
 #include "dps8/dps8_sys.h"
 #include "object_map.h"
 #include "rassert.h"
+#include "stack_header.h"
 
-#define N_PATHS 1
-char *paths[] = {
+#define N_PATHS 2
+char *paths[N_PATHS] = {
+  "tape/word/system_library_1/",
   "tape/word/system_library_standard/"
 };
 
-void get_acc_string(uint64_t *acc_string, char *buf, int buf_len) {
-  int len = (acc_string[0] >> 27) & 0777;
-  rassert(len < buf_len);
+#define N_LOADED_SEGMENT 0x100
+int n_loaded_segment;
+struct loaded_segment {
+  const char *name;
+  int segment;
+  int bitcount;
+} loaded_segment[N_LOADED_SEGMENT];
 
-  static int shifts[4] = {27, 18, 9, 0};
-  for (int i = 0, j = 1; i < len; ++i, ++j)
-    buf[i] = (acc_string[j >> 2] >> shifts[j & 3]) & 0xff;
-  buf[len] = 0;
-}
+#define N_SEGMENT 0x200
+struct loaded_segment *loaded_segment_xref[N_SEGMENT];
+int next_segment;
 
-int main(int argc, char **argv) {
-  if (argc < 3) {
-    printf(
-      "usage: %s object_segment_name entry_segment$entry_name [arguments]\n",
-      argv[0]
-    );
-    exit(EXIT_FAILURE);
-  }
-  char *object_segment_name = argv[1];
-  char *entry_segment, *entry_name;
-  {
-    char *p = strchr(argv[2], '$');
-    if (p) {
-      *p++ = 0;
-      entry_segment = argv[2];
-      entry_name = p;
-    }
-    else {
-      entry_segment = object_segment_name;
-      entry_name = argv[2];
-    }
-  }
+int linkage_segment;
+struct packed_pointer *lot;
+struct packed_pointer *isot;
 
-  // initialize CPU
-  cpu_reset_unit_idx(0, false);
+int stack_segment;
+struct stack_header *stack_header;
 
-  // initialize memory
-  uint64_t *null_segment = mmap(
+#define STACK_OFFSET (sizeof(stack_header) / sizeof(uint64_t))
+
+#define LOT_OFFSET 0
+#define ISOT_OFFSET (LOT_OFFSET + N_SEGMENT)
+#define LINKAGE_OFFSET (ISOT_OFFSET + N_SEGMENT)
+int next_linkage_offset;
+
+int scratch_segment(void) {
+  rassert(next_segment < N_SEGMENT);
+  int index = next_segment++;
+
+  M[index] = (word36 *)mmap(
     NULL,
     01000000 * sizeof(uint64_t),
-    PROT_NONE,
+    PROT_READ | PROT_WRITE,
     MAP_ANONYMOUS | MAP_PRIVATE,
     -1,
     (off_t)0
   );
-  rassert(null_segment != (uint64_t *)-1);
-  for (int i = 0; i < 0100000; ++i)
-    M[i] = (word36 *)null_segment;
+  rassert(M[index] != (word36 *)-1);
+
+  return index;
+}
+
+struct object_map *get_object_map(struct loaded_segment *p) {
+  rassert(p->bitcount % 36 == 0);
+  int wordcount = (p->bitcount / 36) & 0777777;
+  rassert(wordcount >= 1);
+  struct object_map *object_map = (struct object_map *)(
+    M[p->segment] + (
+      (M[p->segment][(wordcount - 1) & 0777777] >> 18) & 0777777
+    )
+  );
+  rassert(object_map->decl_vers == 2);
+  rassert(object_map->identifier[0] == 0157142152137); // 'obj_'
+  rassert(object_map->identifier[1] == 0155141160040); // 'map '
+
+  return object_map;
+}
+
+struct loaded_segment *load_segment(const char *name) {
+  // see if already loaded
+  for (int i = 0; i < n_loaded_segment; ++i)
+    if (strcmp(loaded_segment[i].name, name) == 0)
+      return loaded_segment + i;
+
+  // allocate table entries
+  rassert(n_loaded_segment < N_LOADED_SEGMENT);
+  struct loaded_segment *p =
+    loaded_segment + n_loaded_segment++;
+  p->name = strdup(name);
+  rassert(p->name);
 
-  // search for object segment
-  int fd;
+  rassert(next_segment < N_SEGMENT);
+  p->segment = next_segment++;
+  loaded_segment_xref[p->segment] = p;
+
+  // search for segment in path
   int path_index;
   for (path_index = 0; path_index < N_PATHS; ++path_index) {
-    char name[0x1000];
-    rassert(strlen(paths[path_index]) + strlen(object_segment_name) < sizeof(name));
-    strcpy(name, paths[path_index]);
-    strcat(name, object_segment_name);
-
-    fd = open(name, O_RDONLY);
-    if (fd != -1)
-      goto found_object_segment;
+    char path[0x1000];
+    rassert(strlen(paths[path_index]) + strlen(name) < sizeof(path));
+    strcpy(path, paths[path_index]);
+    strcat(path, name);
+
+    int fd = open(path, O_RDONLY);
+    if (fd != -1) {
+      M[p->segment] = (word36 *)mmap(
+        NULL,
+        01000000 * sizeof(uint64_t),
+        PROT_READ,
+        MAP_SHARED,
+        fd,
+        (off_t)0
+      );
+      rassert(M[p->segment] != (word36 *)-1);
+
+      close(fd);
+      goto found_segment;
+    }
   }
-  fprintf(
-    stderr,
-    "can't find object segment %s in paths list\n",
-    object_segment_name
-  );
+  fprintf(stderr, "can't find segment name %s in paths list\n", name);
   exit(EXIT_FAILURE);
 
-found_object_segment:
+found_segment:
   ;
-  uint64_t *object_segment = mmap(
-    NULL,
-    01000000 * sizeof(uint64_t),
-    PROT_READ,
-    MAP_SHARED,
-    fd,
-    (off_t)0
-  );
-  rassert(object_segment != (uint64_t *)-1);
+  char path[0x1000];
+  rassert(strlen(paths[path_index]) + 4 < sizeof(path));
+  strcpy(path, paths[path_index]);
+  strcat(path, ".dir");
 
-  // search for entry point in object segment
-  uint64_t bitcount;
-  {
-    char index_name[0x1000];
-    rassert(strlen(paths[path_index]) + 4 < sizeof(index_name));
-    strcpy(index_name, paths[path_index]);
-    strcat(index_name, ".dir");
-
-    FILE *fp = fopen(index_name, "r");
-    char line[0x100];
-    while (fgets(line, 0x100, fp)) {
-      char *p = strchr(line, ' ');
-      if (p) {
-        *p++ = 0;
-        if (strcmp(line, object_segment_name) == 0) {
-          bitcount = strtol(p, NULL, 0);
-          goto found_bitcount;
-        }
+  FILE *fp = fopen(path, "r");
+  char line[0x100];
+  while (fgets(line, 0x100, fp)) {
+    char *q = strchr(line, ' ');
+    if (q) {
+      *q++ = 0;
+      if (strcmp(line, name) == 0) {
+        p->bitcount = (int)strtol(q, NULL, 0);
+        goto found_bitcount;
       }
     }
-
-    fprintf(
-      stderr,
-      "can't find object %s in index %s\n",
-      object_segment_name,
-      index_name
-    );
-    exit(EXIT_FAILURE);
   }
 
+  fprintf(stderr, "can't find segment name %s in index %s\n", name, path);
+  exit(EXIT_FAILURE);
+
 found_bitcount:
-  rassert(bitcount % 36 == 0);
-  uint32_t wordcount = (bitcount / 36) & 0777777;
+  ;
+  struct object_map *object_map = get_object_map(p);
 
-  struct object_map *object_map = (struct object_map *)(
-    object_segment +
-      ((object_segment[(wordcount - 1) & 0777777] >> 18) & 0777777)
+  // copy linkage section
+  lot[p->segment] = packed_pointer(linkage_segment, next_linkage_offset);
+  rassert(next_linkage_offset + object_map->linkage_length <= 01000000);
+  memcpy(
+    M[linkage_segment] + next_linkage_offset,
+    M[p->segment] + object_map->linkage_offset,
+    object_map->linkage_length * sizeof(uint64_t)
   );
-  rassert(object_map->decl_vers == 2);
-  rassert(object_map->identifier[0] == 0157142152137); // 'obj_'
-  rassert(object_map->identifier[1] == 0155141160040); // 'map '
+  next_linkage_offset += object_map->linkage_length;
+
+  // copy static section
+  isot[p->segment] = packed_pointer(linkage_segment, next_linkage_offset);
+  rassert(next_linkage_offset + object_map->static_length <= 01000000);
+  memcpy(
+    M[linkage_segment] + next_linkage_offset,
+    M[p->segment] + object_map->static_offset,
+    object_map->static_length * sizeof(uint64_t)
+  );
+  next_linkage_offset += object_map->static_length;
+
+  stack_header->cur_lot_size = next_segment;
+
+  return p;
+}
+
+void get_acc_string(uint64_t *acc_string, char *buf, int buf_len) {
+  int len = (acc_string[0] >> 27) & 0777;
+  rassert(len < buf_len);
+
+  static int shifts[4] = {27, 18, 9, 0};
+  for (int i = 0, j = 1; i < len; ++i, ++j)
+    buf[i] = (acc_string[j >> 2] >> shifts[j & 3]) & 0xff;
+  buf[len] = 0;
+}
+
+void dump_entries(struct loaded_segment *p) {
+  struct object_map *object_map = get_object_map(p);
+  struct definition_header *definition_header = (struct definition_header *)(
+    M[p->segment] + object_map->definition_offset
+  );
+
+  struct definition *definition;
+  for (
+    int definition_relp = (int)definition_header->def_list_relp;
+    definition_relp;
+    definition_relp = (int)definition->forward_relp
+  ) {
+    definition = (struct definition *)(
+      (uint64_t *)definition_header + definition_relp
+    );
+    if (definition->class >= 7)
+      break; // can be dummy entry at end with all zeros and illegal class
+
+    char name[0x20];
+    get_acc_string(
+      (uint64_t *)definition_header + definition->name_relp,
+      name,
+      sizeof(name)
+    );
+    printf(
+      "%06o %s \"%s\" ignore %d entry %d indirect %d thing_relp %06o %s_relp %06o\n",
+      definition_relp,
+      class_names[definition->class],
+      name,
+      definition->flags_ignore,
+      definition->flags_entry,
+      definition->flags_indirect,
+      definition->thing_relp,
+      definition->class == CLASS_SEGNAME ? "first" : "segname",
+      definition->segname_relp
+    );
+  }
+}
 
+int find_entry(
+  struct loaded_segment *p,
+  const char *entry_segment,
+  const char *entry_name,
+  bool entry
+) {
+  struct object_map *object_map = get_object_map(p);
   struct definition_header *definition_header = (struct definition_header *)(
-    object_segment + object_map->definition_offset
+    M[p->segment] + object_map->definition_offset
   );
 
   struct definition *definition;
   for (
-    uint32_t definition_relp = definition_header->def_list_relp;
+    int definition_relp = (int)definition_header->def_list_relp;
     definition_relp;
-    definition_relp = definition->forward_relp
+    definition_relp = (int)definition->forward_relp
   ) {
     definition = (struct definition *)(
       (uint64_t *)definition_header + definition_relp
     );
+    if (definition->class >= 7)
+      break; // can be dummy entry at end with all zeros and illegal class
 
-#if 1
     if (
       definition->class == CLASS_TEXT &&
       !definition->flags_ignore &&
-      definition->flags_entry
+      (!entry || definition->flags_entry)
     ) {
       struct segname_definition *segname_definition =
         (struct segname_definition *)(
@@ -184,54 +275,152 @@ found_bitcount:
         );
 
         if (strcmp(definition_name, entry_name) == 0)
-          goto found_entry;
+          return (int)(object_map->text_offset + definition->thing_relp);
       }
     }
-#else
-    char name[0x20];
-    get_acc_string(
-      (uint64_t *)definition_header + definition->name_relp,
-      name,
-      sizeof(name)
-    );
-    printf(
-      "%06o %s \"%s\" ignore %d entry %d indirect %d thing_relp %06o %s_relp %06o\n",
-      definition_relp,
-      class_names[definition->class],
-      name,
-      definition->flags_ignore,
-      definition->flags_entry,
-      definition->flags_indirect,
-      definition->thing_relp,
-      definition->class == CLASS_SEGNAME ? "first" : "segname",
-      definition->segname_relp
-    );
-#endif
   }
-  printf(
-    "can't find entry %s$%s in object %s\n",
+
+  fprintf(
+    stderr,
+    "can't find entry %s$%s in segment %s\n",
     entry_segment,
     entry_name,
-    object_segment_name
+    p->name
   );
   exit(EXIT_FAILURE);
+}
 
-found_entry:
-  ;
-
-  // map in segment and start executing
-  M[0] = (word36 *)object_segment;
-  cpu.PPR.PRR = 3; // ring
-  cpu.PPR.PSR = 0; // segment
-  cpu.PPR.P = 0; // privilege
-  cpu.PPR.IC = (object_map->text_offset + definition->thing_relp) & 0777777;
+// callback from simulator when fault type 2 occurs
+bool snap_link(void) {
   printf(
-    "entry %s$%s at %06o -> %012llo\n",
-    entry_segment,
-    entry_name,
+    "fault type 2 at %06o:%06o accessing %06o:%06o\n",
+    cpu.PPR.PSR,
     cpu.PPR.IC,
-    M[cpu.PPR.PSR][cpu.PPR.IC]
+    cpu.TPR.TSR,
+    cpu.TPR.CA
   );
+
+  struct loaded_segment *p;
+  struct object_map *object_map;
+  if (
+    cpu.PPR.PSR >= N_SEGMENT ||
+    (p = loaded_segment_xref[cpu.PPR.PSR]) == NULL ||
+    cpu.TPR.TSR != lot[cpu.PPR.PSR].segment ||
+    cpu.TPR.CA < lot[cpu.PPR.PSR].address ||
+    cpu.TPR.CA >= lot[cpu.PPR.PSR].address + (
+      object_map = get_object_map(p)
+    )->linkage_length
+  )
+    return false;
+
+  abort();
+}
+
+int main(int argc, char **argv) {
+  if (argc < 3) {
+    printf(
+      "usage: %s object_segment_name entry_segment$entry_name [arguments]\n",
+      argv[0]
+    );
+    exit(EXIT_FAILURE);
+  }
+  char *object_segment_name = argv[1];
+  char *entry_segment, *entry_name;
+  {
+    char *p = strchr(argv[2], '$');
+    if (p) {
+      *p++ = 0;
+      entry_segment = argv[2];
+      entry_name = p;
+    }
+    else {
+      entry_segment = object_segment_name;
+      entry_name = argv[2];
+    }
+  }
+
+  // initialize CPU
+  cpu_reset_unit_idx(0, false);
+
+  // initialize memory
+  uint64_t *null_segment = mmap(
+    NULL,
+    01000000 * sizeof(uint64_t),
+    PROT_NONE,
+    MAP_ANONYMOUS | MAP_PRIVATE,
+    -1,
+    (off_t)0
+  );
+  rassert(null_segment != (uint64_t *)-1);
+  for (int i = 0; i < 0100000; ++i)
+    M[i] = (word36 *)null_segment;
+  next_segment = 1;
+
+  // create linkage segment
+  linkage_segment = scratch_segment();
+  lot = (struct packed_pointer *)(M[linkage_segment] + LOT_OFFSET);
+  isot = (struct packed_pointer *)(M[linkage_segment] + ISOT_OFFSET);
+  next_linkage_offset = LINKAGE_OFFSET;
+
+  // create stack segment
+  stack_segment = scratch_segment();
+  stack_header = (struct stack_header *)M[stack_segment];
+  stack_header->max_lot_size = N_SEGMENT;
+  stack_header->stack_begin_ptr = its_pointer(stack_segment, STACK_OFFSET);
+  stack_header->stack_end_ptr = its_pointer(stack_segment, STACK_OFFSET);
+  stack_header->lot_ptr = its_pointer(linkage_segment, LOT_OFFSET);
+  stack_header->isot_ptr = its_pointer(linkage_segment, ISOT_OFFSET);
+
+  // load pl1 operators
+  struct loaded_segment *p = load_segment("bound_library_wired_");
+  //dump_entries(p);
+  //exit(EXIT_FAILURE);
+  stack_header->pl1_operators_ptr = its_pointer(
+    p->segment,
+    find_entry(p, "pl1_operators_", "operator_table", false)
+  );
+  stack_header->call_op_ptr = its_pointer(
+    p->segment,
+    find_entry(p, "pl1_operators_", "alm_call", false)
+  );
+  stack_header->push_op_ptr = its_pointer(
+    p->segment,
+    find_entry(p, "pl1_operators_", "alm_push", false)
+  );
+  stack_header->return_op_ptr = its_pointer(
+    p->segment,
+    find_entry(p, "pl1_operators_", "alm_return", false)
+  );
+  stack_header->no_pop_op_ptr = its_pointer(
+    p->segment,
+    find_entry(p, "pl1_operators_", "alm_return_no_pop", false)
+  );
+  stack_header->entry_op_ptr = its_pointer(
+    p->segment,
+    find_entry(p, "pl1_operators_", "alm_entry", false)
+  );
+
+  // set up registers
+  struct loaded_segment *q = load_segment(object_segment_name);
+  set_addr_mode(APPEND_mode);
+
+  // ic (instruction counter)
+  cpu.PPR.PRR = 3; // ring
+  cpu.PPR.PSR = q->segment; // segment
+  cpu.PPR.P = 0; // privilege
+  cpu.PPR.IC = find_entry(q, entry_segment, entry_name, true); // address
+
+  // sp (stack frame pointer)
+  cpu.PR[6].RNR = 3; // ring
+  cpu.PR[6].SNR = p->segment; // segment
+  cpu.PR[6].WORDNO = STACK_OFFSET; // address
+
+  // sb (stack base pointer)
+  cpu.PR[7].RNR = 3; // ring
+  cpu.PR[7].SNR = stack_segment; // segment
+  cpu.PR[7].WORDNO = 0; // address
+
+  // enter simulator
   sim_instr();
 
   return 0;
diff --git a/pl1/stack_header.incl.pl1 b/pl1/stack_header.incl.pl1
new file mode 100644 (file)
index 0000000..ba52394
--- /dev/null
@@ -0,0 +1,98 @@
+/*     BEGIN INCLUDE FILE ... stack_header.incl.pl1 .. 3/72 Bill Silver  */
+/*     modified 7/76 by M. Weaver for *system links and more system use of areas */
+/*     modified 3/77 by M. Weaver to add rnt_ptr */
+/*     Modified April 1983 by C. Hornig for tasking */
+
+/****^  HISTORY COMMENTS:
+  1) change(86-06-24,DGHowe), approve(86-06-24,MCR7396),
+     audit(86-08-05,Schroth), install(86-11-03,MR12.0-1206):
+     added the heap_header_ptr definition.
+  2) change(86-08-12,Kissel), approve(86-08-12,MCR7473),
+     audit(86-10-10,Fawcett), install(86-11-03,MR12.0-1206):
+     Modified to support control point management.  These changes were actually
+     made in February 1985 by G. Palter.
+  3) change(86-10-22,Fawcett), approve(86-10-22,MCR7473),
+     audit(86-10-22,Farley), install(86-11-03,MR12.0-1206):
+     Remove the old_lot pointer and replace it with cpm_data_ptr. Use the 18
+     bit pad after cur_lot_size for the cpm_enabled. This was done to save some
+     space int the stack header and change the cpd_ptr unal to cpm_data_ptr
+     (ITS pair).
+                                                   END HISTORY COMMENTS */
+
+/* format: style2 */
+
+     dcl          sb                 ptr;              /* the  main pointer to the stack header */
+
+     dcl          1 stack_header             based (sb) aligned,
+            2 pad1           (4) fixed bin,    /*  (0) also used as arg list by outward_call_handler  */
+            2 cpm_data_ptr           ptr,              /*  (4)  pointer to control point which owns this stack */
+            2 combined_stat_ptr  ptr,          /*  (6)  pointer to area containing separate static */
+            2 clr_ptr        ptr,              /*  (8)  pointer to area containing linkage sections */
+            2 max_lot_size           fixed bin (17) unal,      /*  (10) DU  number of words allowed in lot */
+            2 main_proc_invoked  fixed bin (11) unal,  /*  (10) DL  nonzero if main procedure invoked in run unit */
+            2 have_static_vlas   bit (1) unal,         /*  (10) DL  "1"b if (very) large arrays are being used in static */
+            2 pad4           bit (2) unal,
+            2 run_unit_depth     fixed bin (2) unal,   /*  (10) DL  number of active run units stacked */
+            2 cur_lot_size           fixed bin (17) unal,      /*  (11) DU  number of words (entries) in lot */
+            2 cpm_enabled            bit (18) unal,    /*  (11) DL  non-zero if control point management is enabled */
+            2 system_free_ptr    ptr,          /*  (12)  pointer to system storage area */
+            2 user_free_ptr      ptr,          /*  (14)  pointer to user storage area */
+            2 null_ptr       ptr,              /*  (16)  */
+            2 stack_begin_ptr    ptr,          /*  (18)  pointer to first stack frame on the stack */
+            2 stack_end_ptr      ptr,          /*  (20)  pointer to next useable stack frame */
+            2 lot_ptr        ptr,              /*  (22)  pointer to the lot for the current ring */
+            2 signal_ptr             ptr,              /*  (24)  pointer to signal procedure for current ring */
+            2 bar_mode_sp            ptr,              /*  (26)  value of sp before entering bar mode */
+            2 pl1_operators_ptr  ptr,          /*  (28)  pointer to pl1_operators_$operator_table */
+            2 call_op_ptr            ptr,              /*  (30)  pointer to standard call operator */
+            2 push_op_ptr            ptr,              /*  (32)  pointer to standard push operator */
+            2 return_op_ptr      ptr,          /*  (34)  pointer to standard return operator */
+            2 return_no_pop_op_ptr
+                             ptr,              /*  (36)  pointer to standard return / no pop operator */
+            2 entry_op_ptr           ptr,              /*  (38)  pointer to standard entry operator */
+            2 trans_op_tv_ptr    ptr,          /*  (40)  pointer to translator operator ptrs */
+            2 isot_ptr       ptr,              /*  (42)  pointer to ISOT */
+            2 sct_ptr        ptr,              /*  (44)  pointer to System Condition Table */
+            2 unwinder_ptr           ptr,              /*  (46)  pointer to unwinder for current ring */
+            2 sys_link_info_ptr  ptr,          /*  (48)  pointer to *system link name table */
+            2 rnt_ptr        ptr,              /*  (50)  pointer to Reference Name Table */
+            2 ect_ptr        ptr,              /*  (52)  pointer to event channel table */
+            2 assign_linkage_ptr ptr,          /*  (54)  pointer to storage for (obsolete) hcs_$assign_linkage */
+            2 heap_header_ptr     ptr,         /*  (56)  pointer to the heap header for this ring */
+            2 trace,
+              3 frames,
+                4 count              fixed bin,                /*  (58)  number of trace frames */
+                4 top_ptr            ptr unal,         /*  (59)  pointer to last trace frame */
+              3 in_trace             bit (36) aligned, /*  (60)  trace antirecursion flag */
+            2 pad2           bit (36),         /*  (61) */
+               2 pad5        pointer;          /*  (62)  pointer to future stuff */
+
+/*     The following offset refers to a table within the  pl1  operator table.  */
+
+     dcl          tv_offset          fixed bin init (361) internal static;
+                                               /* (551) octal */
+
+
+/*     The following constants are offsets within this transfer vector table.  */
+
+     dcl          (
+          call_offset        fixed bin init (271),
+          push_offset        fixed bin init (272),
+          return_offset              fixed bin init (273),
+          return_no_pop_offset   fixed bin init (274),
+          entry_offset       fixed bin init (275)
+          )                  internal static;
+
+
+
+
+
+/*     The following declaration  is an overlay of the whole stack header.   Procedures which
+       move the whole stack header should use this overlay.
+*/
+
+     dcl          stack_header_overlay   (size (stack_header)) fixed bin based (sb);
+
+
+
+/*     END INCLUDE FILE ... stack_header.incl.pl1 */
diff --git a/pointer.c b/pointer.c
new file mode 100644 (file)
index 0000000..f17bcb1
--- /dev/null
+++ b/pointer.c
@@ -0,0 +1,21 @@
+#include "pointer.h"
+
+struct pointer pointer(int address) {
+  struct pointer p = {0, 0, address, 0};
+  return p;
+}
+
+struct itp_pointer itp_pointer(int pair, int address) {
+  struct itp_pointer p = {041, 0, address, pair, 0};
+  return p;
+}
+
+struct its_pointer its_pointer(int segment, int address) {
+  struct its_pointer p = {043, 0, segment, 0, 0, 0, address, 0};
+  return p;
+}
+
+struct packed_pointer packed_pointer(int segment, int address) {
+  struct packed_pointer p = {address, segment, 0};
+  return p;
+}
diff --git a/pointer.h b/pointer.h
new file mode 100644 (file)
index 0000000..f9f720f
--- /dev/null
+++ b/pointer.h
@@ -0,0 +1,43 @@
+#ifndef _POINTER_H
+#define _POINTER_H
+
+#include <stdint.h>
+
+struct pointer {
+  uint64_t modifier : 6;
+  uint64_t tally : 12;
+  uint64_t address : 18;
+  uint64_t dummy0 : 28;
+};
+
+struct itp_pointer {
+  uint64_t modifier : 6;
+  uint64_t tally : 12;
+  int64_t address : 15;
+  uint64_t pair : 3;
+  uint64_t dummy0 : 28;
+};
+
+struct its_pointer {
+  uint64_t modifier0 : 6;
+  uint64_t tally0 : 12;
+  uint64_t segment : 18;
+  uint64_t dummy0 : 28;
+  uint64_t modifier1 : 6;
+  uint64_t tally1 : 12;
+  uint64_t address : 18;
+  uint64_t dummy1 : 28;
+};
+
+struct packed_pointer {
+  uint64_t address : 18;
+  uint64_t segment : 18;
+  uint64_t dummy0 : 28;
+};
+
+struct pointer pointer(int address);
+struct itp_pointer itp_pointer(int pair, int address);
+struct its_pointer its_pointer(int segment, int address);
+struct packed_pointer packed_pointer(int segment, int address);
+
+#endif
diff --git a/stack_header.h b/stack_header.h
new file mode 100644 (file)
index 0000000..efab499
--- /dev/null
@@ -0,0 +1,163 @@
+#ifndef _STACK_HEADER_H
+#define _STACK_HEADER_H
+
+#include "pointer.h"
+
+// see pl1/stack_header.incl.pl1
+
+// dcl sb ptr; /* the main pointer to the stack header */
+
+// dcl 1 stack_header based (sb) aligned,
+struct stack_header {
+  // 2 pad1 (4) fixed bin, /* (0) also used as arg list by outward_call_handler */
+  uint64_t pad1[4];
+
+  // 2 cpm_data_ptr ptr, /* (4) pointer to control point which owns this stack */
+  struct its_pointer cpm_data_ptr;
+
+  // 2 combined_stat_ptr ptr, /* (6) pointer to area containing separate static */
+  struct its_pointer combined_stat_ptr;
+
+  // 2 clr_ptr ptr, /* (8) pointer to area containing linkage sections */
+  struct its_pointer clr_ptr;
+
+  // 2 max_lot_size fixed bin (17) unal, /* (10) DU number of words allowed in lot */
+  // 2 main_proc_invoked fixed bin (11) unal, /* (10) DL nonzero if main procedure invoked in run unit */
+  // 2 have_static_vlas bit (1) unal, /* (10) DL "1"b if (very) large arrays are being used in static */
+  // 2 pad4 bit (2) unal,
+  // 2 run_unit_depth fixed bin (2) unal, /* (10) DL number of active run units stacked */
+  int64_t unit_depth : 3;
+  uint64_t pad4 : 2;
+  uint64_t have_static_vlas : 1;
+  int64_t main_proc_invoked : 12;
+  int64_t max_lot_size : 18;
+  uint64_t dummy0 : 28;
+
+  // 2 cur_lot_size fixed bin (17) unal, /* (11) DU number of words (entries) in lot */
+  // 2 cpm_enabled bit (18) unal, /* (11) DL non-zero if control point management is enabled */
+  uint64_t cpm_enabled : 18;
+  int64_t cur_lot_size : 18;
+  uint64_t dummy1 : 28;
+
+  // 2 system_free_ptr ptr, /* (12) pointer to system storage area */
+  struct its_pointer system_free_ptr;
+
+  // 2 user_free_ptr ptr, /* (14) pointer to user storage area */
+  struct its_pointer user_free_ptr;
+
+  // 2 null_ptr ptr, /* (16) */
+  struct its_pointer null_ptr;
+
+  // 2 stack_begin_ptr ptr, /* (18) pointer to first stack frame on the stack */
+  struct its_pointer stack_begin_ptr;
+
+  // 2 stack_end_ptr ptr, /* (20) pointer to next useable stack frame */
+  struct its_pointer stack_end_ptr;
+
+  // 2 lot_ptr ptr, /* (22) pointer to the lot for the current ring */
+  struct its_pointer lot_ptr;
+
+  // 2 signal_ptr ptr, /* (24) pointer to signal procedure for current ring */
+  struct its_pointer signal_ptr;
+
+  // 2 bar_mode_sp ptr, /* (26) value of sp before entering bar mode */
+  struct its_pointer bar_mode_sp;
+
+  // 2 pl1_operators_ptr ptr, /* (28) pointer to pl1_operators_$operator_table */
+  struct its_pointer pl1_operators_ptr;
+
+  // 2 call_op_ptr ptr, /* (30) pointer to standard call operator */
+  struct its_pointer call_op_ptr;
+
+  // 2 push_op_ptr ptr, /* (32) pointer to standard push operator */
+  struct its_pointer push_op_ptr;
+
+  // 2 return_op_ptr ptr, /* (34) pointer to standard return operator */
+  struct its_pointer return_op_ptr;
+
+  // 2 return_no_pop_op_ptr
+  // ptr, /* (36) pointer to standard return / no pop operator */
+  struct its_pointer no_pop_op_ptr;
+
+  // 2 entry_op_ptr ptr, /* (38) pointer to standard entry operator */
+  struct its_pointer entry_op_ptr;
+
+  // 2 trans_op_tv_ptr ptr, /* (40) pointer to translator operator ptrs */
+  struct its_pointer trans_op_tv_ptr;
+
+  // 2 isot_ptr ptr, /* (42) pointer to ISOT */
+  struct its_pointer isot_ptr;
+
+  // 2 sct_ptr ptr, /* (44) pointer to System Condition Table */
+  struct its_pointer sct_ptr;
+
+  // 2 unwinder_ptr ptr, /* (46) pointer to unwinder for current ring */
+  struct its_pointer unwinder_ptr;
+
+  // 2 sys_link_info_ptr ptr, /* (48) pointer to *system link name table */
+  struct its_pointer sys_link_info_ptr;
+
+  // 2 rnt_ptr ptr, /* (50) pointer to Reference Name Table */
+  struct its_pointer rnt_ptr;
+
+  // 2 ect_ptr ptr, /* (52) pointer to event channel table */
+  struct its_pointer ect_ptr;
+
+  // 2 assign_linkage_ptr ptr, /* (54) pointer to storage for (obsolete) hcs_$assign_linkage */
+  struct its_pointer assign_linkage_ptr;
+
+  // 2 heap_header_ptr ptr, /* (56) pointer to the heap header for this ring */
+  struct its_pointer heap_header_ptr;
+
+  // 2 trace,
+  // 3 frames,
+  // 4 count fixed bin, /* (58) number of trace frames */
+  int64_t trace_frames_count;
+
+  // 4 top_ptr ptr unal, /* (59) pointer to last trace frame */
+  uint64_t trace_frames_top_ptr;
+
+  // 3 in_trace bit (36) aligned, /* (60) trace antirecursion flag */
+  uint64_t trace_in_trace;
+
+  // 2 pad2 bit (36), /* (61) */
+  uint64_t pad2;
+
+  // 2 pad5 pointer; /* (62) pointer to future stuff */
+  struct its_pointer pad5;
+};
+
+/* The following offset refers to a table within the pl1 operator table. */
+
+// dcl tv_offset fixed bin init (361) internal static;
+ /* (551) octal */
+#define TV_OFFSET 361
+
+/* The following constants are offsets within this transfer vector table. */
+
+// dcl (
+enum {
+  // call_offset fixed bin init (271),
+  call_offset = 271,
+
+  // push_offset fixed bin init (272),
+  push_offset = 272,
+
+  // return_offset fixed bin init (273),
+  return_offset = 273,
+
+  // return_no_pop_offset fixed bin init (274),
+  no_pop_offset = 274,
+
+  // entry_offset fixed bin init (275)
+  entry_offset = 275
+// ) internal static;
+};
+
+/* The following declaration is an overlay of the whole stack header. Procedures which
+ move the whole stack header should use this overlay.
+*/
+
+// dcl stack_header_overlay (size (stack_header)) fixed bin based (sb);
+
+#endif