Can now run calc$calc, echoes back a single number, if try to add numbers it falls...
authorNick Downing <nick@ndcode.org>
Sun, 20 Oct 2019 13:44:07 +0000 (00:44 +1100)
committerNick Downing <nick@ndcode.org>
Sun, 20 Oct 2019 13:44:19 +0000 (00:44 +1100)
12 files changed:
Makefile
dps8/dps8_append.c
dps8/dps8_append.h
dps8/dps8_cpu.c
dps8/dps8_cpu.h
dps8/dps8_iefp.c
dps8/dps8_ins.c
dump_entries.c
dump_segments.c
multics_sim.c
pl1/stack_frame.incl.pl1 [new file with mode: 0644]
stack_frame.h [new file with mode: 0644]

index 443c873..a4057b2 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-CFLAGS=-g -std=c99 -U__STRICT_ANSI__ -IdecNumber -Idps8 -D_GNU_SOURCE -DUSE_READER_THREAD -DUSE_INT64 -DTESTING -Wall -Wno-comment -Wno-unused-label -Wno-unused-result -Wno-unused-value -Wno-unused-variable -Wno-unused-function
+CFLAGS=-g -std=c99 -U__STRICT_ANSI__ -IdecNumber -Idps8 -D_GNU_SOURCE -DUSE_READER_THREAD -DUSE_INT64 -DTESTING -DEMULATOR_ONLY=1 -Wall -Wno-comment -Wno-unused-label -Wno-unused-result -Wno-unused-value -Wno-unused-variable -Wno-unused-function
 #-O3
 
 all: multics_sim dump_entries dump_segments
index fb3a899..c68b4dc 100644 (file)
@@ -1239,7 +1239,7 @@ static char *str_pct (processor_cycle_type t)
 
 // CANFAULT
 
-word24 do_append_cycle (processor_cycle_type thisCycle, word36 * data,
+/*word24*/word36 do_append_cycle (processor_cycle_type thisCycle, word36 * data,
                       uint nWords)
   {
     DCDstruct * i = & cpu.currentInstruction;
@@ -1295,7 +1295,7 @@ word24 do_append_cycle (processor_cycle_type thisCycle, word36 * data,
 #define FMSG(x) 
     FMSG (char * acvFaultsMsg = "<unknown>";)
 
-    word24 finalAddress = (word24) -1;  // not everything requires a final
+    /*word24*/word36 finalAddress = (/*word24*/word36) -1;  // not everything requires a final
                                         // address
     
 ////////////////////////////////////////
@@ -1922,54 +1922,54 @@ word24 do_append_cycle (processor_cycle_type thisCycle, word36 * data,
       }
     PNL (cpu.APUMemAddr = finalAddress;)
     
-    DBGAPP ("do_append_cycle(H:FANP): (%05o:%06o) finalAddress=%08o\n",
+    DBGAPP ("do_append_cycle(H:FANP): (%05o:%06o) finalAddress=%011"PRIo64/*%08o*/"\n",
             cpu.TPR.TSR, cpu.TPR.CA, finalAddress);
     
     //if (thisCycle == ABSA_CYCLE)
     //    goto J;
-    goto HI;
-    
-I:;
-
-// Set PTW.M
-
-    DBGAPP ("do_append_cycle(I): FAP\n");
-#ifdef LOCKLESS
-    if ((StrOp ||
-        thisCycle == OPERAND_RMW ||
-        thisCycle == APU_DATA_RMW) && cpu.PTW->M == 0)  // is this the right way to do this?
-#else
-    if (StrOp && cpu.PTW->M == 0)  // is this the right way to do this?
-#endif
-      {
-       modify_ptw (cpu.SDW, cpu.TPR.CA);
-      }
-    
-    // final address paged
-    set_apu_status (apuStatus_FAP);
-    PNL (L68_ (cpu.apu.state |= apu_FAP;))
-    
-    word24 y2 = cpu.TPR.CA % 1024;
-    
-    // AL39: The hardware ignores low order bits of the main memory page
-    // address according to page size    
-    finalAddress = (((word24)cpu.PTW->ADDR & 0777760) << 6) + y2; 
-    finalAddress &= 0xffffff;
-    PNL (cpu.APUMemAddr = finalAddress;)
-    
-#ifdef L68
-    if (cpu.MR_cache.emr && cpu.MR_cache.ihr)
-      add_APU_history (APUH_FAP);
-#endif
-    DBGAPP ("do_append_cycle(H:FAP): (%05o:%06o) finalAddress=%08o\n",
-            cpu.TPR.TSR, cpu.TPR.CA, finalAddress);
-
-    //if (thisCycle == ABSA_CYCLE)
-    //    goto J;
-    goto HI;
-
-HI:
-    DBGAPP ("do_append_cycle(HI)\n");
+//    goto HI;
+//    
+//I:;
+//
+//// Set PTW.M
+//
+//    DBGAPP ("do_append_cycle(I): FAP\n");
+//#ifdef LOCKLESS
+//    if ((StrOp ||
+//        thisCycle == OPERAND_RMW ||
+//        thisCycle == APU_DATA_RMW) && cpu.PTW->M == 0)  // is this the right way to do this?
+//#else
+//    if (StrOp && cpu.PTW->M == 0)  // is this the right way to do this?
+//#endif
+//      {
+//       modify_ptw (cpu.SDW, cpu.TPR.CA);
+//      }
+//    
+//    // final address paged
+//    set_apu_status (apuStatus_FAP);
+//    PNL (L68_ (cpu.apu.state |= apu_FAP;))
+//    
+//    word24 y2 = cpu.TPR.CA % 1024;
+//    
+//    // AL39: The hardware ignores low order bits of the main memory page
+//    // address according to page size    
+//    finalAddress = (((word24)cpu.PTW->ADDR & 0777760) << 6) + y2; 
+//    finalAddress &= 0xffffff;
+//    PNL (cpu.APUMemAddr = finalAddress;)
+//    
+//#ifdef L68
+//    if (cpu.MR_cache.emr && cpu.MR_cache.ihr)
+//      add_APU_history (APUH_FAP);
+//#endif
+//    DBGAPP ("do_append_cycle(H:FAP): (%05o:%06o) finalAddress=%08o\n",
+//            cpu.TPR.TSR, cpu.TPR.CA, finalAddress);
+//
+//    //if (thisCycle == ABSA_CYCLE)
+//    //    goto J;
+//    goto HI;
+//
+//HI:
+//    DBGAPP ("do_append_cycle(HI)\n");
 
     // isolts 870
     if (thisCycle != ABSA_CYCLE)
index b658a37..5f22ef0 100644 (file)
@@ -115,7 +115,7 @@ static inline void set_apu_status (apuStatusBits status)
   }
 
 t_stat dump_sdwam (void);
-word24 do_append_cycle (processor_cycle_type thisCycle, 
+/*word24*/word36 do_append_cycle (processor_cycle_type thisCycle, 
                       word36 * data, uint nWords);
 void do_ldbr (word36 * Ypair);
 void do_sdbr (word36 * Ypair);
index 581270d..de3f970 100644 (file)
@@ -2842,7 +2842,7 @@ sim_debug (DBG_TRACEEXT, & cpu_dev, "fetchCycle bit 29 sets XSF to 0\n");
 #endif
 
               // absolute address of fault YPair
-              word24 addr = fltAddress + 2 * cpu.faultNumber;
+              /*word24*/word36 addr = fltAddress + 2 * cpu.faultNumber;
   
               if (cpu.restart)
                 {
@@ -3085,10 +3085,10 @@ t_stat set_mem_watch (int32 arg, const char * buf)
  */
 
 #ifndef SPEED
-static void nem_check (word24 addr, char * context)
+static void nem_check (/*word24*/word36 addr, char * context)
   {
 #ifdef SCUMEM
-    word24 offset;
+    /*word24*/word36 offset;
     if (lookup_cpu_mem_map (addr, & offset) < 0)
       {
         doFault (FAULT_STR, fst_str_nea,  context);
@@ -3118,7 +3118,7 @@ static uint get_scu_unit_idx (word24 addr, word24 * offset)
 #endif
 
 #if !defined(SPEED) || !defined(INLINE_CORE)
-int32 core_read (word24 addr, word36 *data, const char * ctx)
+int32 core_read (/*word24*/word36 addr, word36 *data, const char * ctx)
   {
     PNL (cpu.portBusy = true;)
 #ifdef ISOLTS
@@ -3153,23 +3153,24 @@ int32 core_read (word24 addr, word36 *data, const char * ctx)
 #endif
 #endif
 #ifdef SCUMEM
-    word24 offset;
+    /*word24*/word36 offset;
     uint scu_unit_idx = get_scu_unit_idx (addr, & offset);
     LOCK_MEM_RD;
     *data = scu [scu_unit_idx].M[offset] & DMASK;
     UNLOCK_MEM;
     if (watch_bits [addr])
       {
-        sim_msg ("WATCH [%"PRId64"] %05o:%06o read   %08o %012"PRIo64" "
+        sim_msg ("WATCH [%"PRId64"] %05o:%06o read   %011"PRIo64/*%08o*/" %012"PRIo64" "
                     "(%s)\n", cpu.cycleCnt, cpu.PPR.PSR, cpu.PPR.IC, addr,
                     * data, ctx);
       }
 #else
 #ifndef LOCKLESS
+ printf("addr %012llo\n", addr);
     if (M[(addr >> 18) & 077777][addr & 0777777] & MEM_UNINITIALIZED)
       {
         sim_debug (DBG_WARN, & cpu_dev,
-                   "Unitialized memory accessed at address %08o; "
+                   "Unitialized memory accessed at address %011"PRIo64/*%08o*/"; "
                    "IC is 0%06o:0%06o (%s(\n",
                    addr, cpu.PPR.PSR, cpu.PPR.IC, ctx);
       }
@@ -3177,7 +3178,7 @@ int32 core_read (word24 addr, word36 *data, const char * ctx)
 #ifndef SPEED
     if (watch_bits [addr])
       {
-        sim_msg ("WATCH [%"PRId64"] %05o:%06o read   %08o %012"PRIo64" "
+        sim_msg ("WATCH [%"PRId64"] %05o:%06o read   %011"PRIo64/*%08o*/" %012"PRIo64" "
                     "(%s)\n",
                     cpu.cycleCnt, cpu.PPR.PSR, cpu.PPR.IC, addr, M[(addr >> 18) & 077777][addr & 0777777],
                     ctx);
@@ -3199,7 +3200,7 @@ int32 core_read (word24 addr, word36 *data, const char * ctx)
     cpu.rTRticks ++;
 #endif
     sim_debug (DBG_CORE, & cpu_dev,
-               "core_read  %08o %012"PRIo64" (%s)\n",
+               "core_read  %011"PRIo64/*%08o*/" %012"PRIo64" (%s)\n",
                 addr, * data, ctx);
     PNL (trackport (addr, * data));
     return 0;
@@ -3207,7 +3208,7 @@ int32 core_read (word24 addr, word36 *data, const char * ctx)
 #endif
 
 #ifdef LOCKLESS
-int32 core_read_lock (word24 addr, word36 *data, const char * ctx)
+int32 core_read_lock (/*word24*/word36 addr, word36 *data, const char * ctx)
 {
 #ifdef ISOLTS
     if (cpu.switches.useMap)
@@ -3227,7 +3228,7 @@ int32 core_read_lock (word24 addr, word36 *data, const char * ctx)
 #endif
     LOCK_CORE_WORD(addr);
     if (cpu.locked_addr != 0) {
-      sim_warn ("core_read_lock: locked %08o locked_addr %08o %c %05o:%06o\n",
+      sim_warn ("core_read_lock: locked %011"PRIo64/*%08o*/" locked_addr %011"PRIo64/*%08o*/" %c %05o:%06o\n",
                 addr, cpu.locked_addr, current_running_cpu_idx + 'A',
                 cpu.PPR.PSR, cpu.PPR.IC);
       core_unlock_all ();
@@ -3241,7 +3242,7 @@ int32 core_read_lock (word24 addr, word36 *data, const char * ctx)
 #endif
 
 #if !defined(SPEED) || !defined(INLINE_CORE)
-int core_write (word24 addr, word36 data, const char * ctx)
+int core_write (/*word24*/word36 addr, word36 data, const char * ctx)
   {
     PNL (cpu.portBusy = true;)
 #ifdef ISOLTS
@@ -3273,14 +3274,14 @@ int core_write (word24 addr, word36 data, const char * ctx)
       }
 #endif
 #ifdef SCUMEM
-    word24 offset;
+    /*word24*/word36 offset;
     uint sci_unit_idx = get_scu_unit_idx (addr, & offset);
     LOCK_MEM_WR;
     scu[sci_unit_idx].M[offset] = data & DMASK;
     UNLOCK_MEM;
     if (watch_bits [addr])
       {
-        sim_msg ("WATCH [%"PRId64"] %05o:%06o write   %08o %012"PRIo64" "
+        sim_msg ("WATCH [%"PRId64"] %05o:%06o write   %011"PRIo64/*%08o*/" %012"PRIo64" "
                     "(%s)\n", cpu.cycleCnt, cpu.PPR.PSR, cpu.PPR.IC, addr, 
                     scu[sci_unit_idx].M[offset], ctx);
       }
@@ -3296,7 +3297,7 @@ int core_write (word24 addr, word36 data, const char * ctx)
 #ifndef SPEED
     if (watch_bits [addr])
       {
-        sim_msg ("WATCH [%"PRId64"] %05o:%06o write  %08o %012"PRIo64" "
+        sim_msg ("WATCH [%"PRId64"] %05o:%06o write  %011"PRIo64/*%08o*/" %012"PRIo64" "
                     "(%s)\n", cpu.cycleCnt, cpu.PPR.PSR, cpu.PPR.IC, addr, 
                     M[(addr >> 18) & 077777][addr & 0777777], ctx);
         traceInstruction (0);
@@ -3307,7 +3308,7 @@ int core_write (word24 addr, word36 data, const char * ctx)
     cpu.rTRticks ++;
 #endif
     sim_debug (DBG_CORE, & cpu_dev,
-               "core_write %08o %012"PRIo64" (%s)\n",
+               "core_write %011"PRIo64/*%08o*/" %012"PRIo64" (%s)\n",
                 addr, data, ctx);
     PNL (trackport (addr, data));
     return 0;
@@ -3315,7 +3316,7 @@ int core_write (word24 addr, word36 data, const char * ctx)
 #endif
 
 #ifdef LOCKLESS
-int core_write_unlock (word24 addr, word36 data, const char * ctx)
+int core_write_unlock (/*word24*/word36 addr, word36 data, const char * ctx)
 {
 #ifdef ISOLTS
     if (cpu.switches.useMap)
@@ -3335,7 +3336,7 @@ int core_write_unlock (word24 addr, word36 data, const char * ctx)
 #endif
     if (cpu.locked_addr != addr)
       {
-        sim_warn ("core_write_unlock: locked %08o locked_addr %08o %c %05o:%06o\n",
+        sim_warn ("core_write_unlock: locked %011"PRIo64/*%08o*/" locked_addr %011"PRIo64/*%08o*/" %c %05o:%06o\n",
                   addr, cpu.locked_addr, current_running_cpu_idx + 'A',
                   cpu.PPR.PSR, cpu.PPR.IC);
        core_unlock_all ();
@@ -3349,7 +3350,7 @@ int core_write_unlock (word24 addr, word36 data, const char * ctx)
 int core_unlock_all ()
 {
   if (cpu.locked_addr != 0) {
-      sim_warn ("core_unlock_all: locked %08o %c %05o:%06o\n",
+      sim_warn ("core_unlock_all: locked %011"PRIo64/*%08o*/" %c %05o:%06o\n",
                 cpu.locked_addr, current_running_cpu_idx + 'A',
                 cpu.PPR.PSR, cpu.PPR.IC);
       STORE_REL_CORE_WORD(cpu.locked_addr, M[(cpu.locked_addr >> 18) & 077777][cpu.locked_addr & 0777777]);
@@ -3360,7 +3361,7 @@ int core_unlock_all ()
 #endif
 
 #if !defined(SPEED) || !defined(INLINE_CORE)
-int core_write_zone (word24 addr, word36 data, const char * ctx)
+int core_write_zone (/*word24*/word36 addr, word36 data, const char * ctx)
   {
     PNL (cpu.portBusy = true;)
 #ifdef ISOLTS
@@ -3376,7 +3377,7 @@ int core_write_zone (word24 addr, word36 data, const char * ctx)
       }
 #endif
 #ifdef SCUMEM
-    word24 offset;
+    /*word24*/word36 offset;
     uint sci_unit_idx = get_scu_unit_idx (addr, & offset);
     LOCK_MEM_WR;
     scu[sci_unit_idx].M[offset] = (scu[sci_unit_idx].M[offset] & ~cpu.zone) |
@@ -3385,7 +3386,7 @@ int core_write_zone (word24 addr, word36 data, const char * ctx)
     cpu.useZone = false; // Safety
     if (watch_bits [addr])
       {
-        sim_msg ("WATCH [%"PRId64"] %05o:%06o writez %08o %012"PRIo64" "
+        sim_msg ("WATCH [%"PRId64"] %05o:%06o writez %011"PRIo64/*%08o*/" %012"PRIo64" "
                     "(%s)\n", cpu.cycleCnt, cpu.PPR.PSR, cpu.PPR.IC, addr, 
                     scu[sci_unit_idx].M[offset], ctx);
       }
@@ -3420,7 +3421,7 @@ int core_write_zone (word24 addr, word36 data, const char * ctx)
 #ifndef SPEED
     if (watch_bits [addr])
       {
-        sim_msg ("WATCH [%"PRId64"] %05o:%06o writez %08o %012"PRIo64" "
+        sim_msg ("WATCH [%"PRId64"] %05o:%06o writez %011"PRIo64/*%08o*/" %012"PRIo64" "
                     "(%s)\n", cpu.cycleCnt, cpu.PPR.PSR, cpu.PPR.IC, addr, 
                     M[(addr >> 18) & 077777][addr & 0777777], ctx);
         traceInstruction (0);
@@ -3431,7 +3432,7 @@ int core_write_zone (word24 addr, word36 data, const char * ctx)
     cpu.rTRticks ++;
 #endif
     sim_debug (DBG_CORE, & cpu_dev,
-               "core_write_zone %08o %012"PRIo64" (%s)\n",
+               "core_write_zone %011"PRIo64/*%08o*/" %012"PRIo64" (%s)\n",
                 addr, data, ctx);
     PNL (trackport (addr, data));
     return 0;
@@ -3439,15 +3440,15 @@ int core_write_zone (word24 addr, word36 data, const char * ctx)
 #endif
 
 #if !defined(SPEED) || !defined(INLINE_CORE)
-int core_read2 (word24 addr, word36 *even, word36 *odd, const char * ctx)
+int core_read2 (/*word24*/word36 addr, word36 *even, word36 *odd, const char * ctx)
   {
     PNL (cpu.portBusy = true;)
     if (addr & 1)
       {
         sim_debug (DBG_MSG, & cpu_dev,
-                   "warning: subtracting 1 from pair at %o in "
+                   "warning: subtracting 1 from pair at %"PRIo64/*%o*/" in "
                    "core_read2 (%s)\n", addr, ctx);
-        addr &= (word24)~1; /* make it an even address */
+        addr &= (/*word24*/word36)~1; /* make it an even address */
       }
 #ifdef ISOLTS
     if (cpu.switches.useMap)
@@ -3481,7 +3482,7 @@ int core_read2 (word24 addr, word36 *even, word36 *odd, const char * ctx)
 #endif
 #endif
 #ifdef SCUMEM
-    word24 offset;
+    /*word24*/word36 offset;
     uint sci_unit_idx = get_scu_unit_idx (addr, & offset);
     LOCK_MEM_RD;
     *even = scu [sci_unit_idx].M[offset++] & DMASK;
@@ -3489,14 +3490,14 @@ int core_read2 (word24 addr, word36 *even, word36 *odd, const char * ctx)
 #ifndef SPEED
     if (watch_bits [addr])
       {
-        sim_msg ("WATCH [%"PRId64"] %05o:%06o read2  %08o %012"PRIo64" "
+        sim_msg ("WATCH [%"PRId64"] %05o:%06o read2  %011"PRIo64/*%08o*/" %012"PRIo64" "
                     "(%s)\n", cpu.cycleCnt, cpu.PPR.PSR, cpu.PPR.IC, addr,
                     * even, ctx);
       }
 #endif
 
     sim_debug (DBG_CORE, & cpu_dev,
-               "core_read2 %08o %012"PRIo64" (%s)\n",
+               "core_read2 %011"PRIo64/*%08o*/" %012"PRIo64" (%s)\n",
                 addr, * even, ctx);
     LOCK_MEM_RD;
     *odd = scu [sci_unit_idx].M[offset] & DMASK;
@@ -3504,21 +3505,21 @@ int core_read2 (word24 addr, word36 *even, word36 *odd, const char * ctx)
 #ifndef SPEED
     if (watch_bits [addr+1])
       {
-        sim_msg ("WATCH [%"PRId64"] %05o:%06o read2  %08o %012"PRIo64" "
+        sim_msg ("WATCH [%"PRId64"] %05o:%06o read2  %011"PRIo64/*%08o*/" %012"PRIo64" "
                     "(%s)\n", cpu.cycleCnt, cpu.PPR.PSR, cpu.PPR.IC, addr+1,
                     * odd, ctx);
       }
 #endif
 
     sim_debug (DBG_CORE, & cpu_dev,
-               "core_read2 %08o %012"PRIo64" (%s)\n",
+               "core_read2 %011"PRIo64/*%08o*/" %012"PRIo64" (%s)\n",
                 addr+1, * odd, ctx);
 #else
 #ifndef LOCKLESS
     if (M[(addr >> 18) & 077777][addr & 0777777] & MEM_UNINITIALIZED)
       {
         sim_debug (DBG_WARN, & cpu_dev,
-                   "Unitialized memory accessed at address %08o; "
+                   "Unitialized memory accessed at address %011"PRIo64/*%08o*/"; "
                    "IC is 0%06o:0%06o (%s)\n",
                    addr, cpu.PPR.PSR, cpu.PPR.IC, ctx);
       }
@@ -3526,7 +3527,7 @@ int core_read2 (word24 addr, word36 *even, word36 *odd, const char * ctx)
 #ifndef SPEED
     if (watch_bits [addr])
       {
-        sim_msg ("WATCH [%"PRId64"] %05o:%06o read2  %08o %012"PRIo64" "
+        sim_msg ("WATCH [%"PRId64"] %05o:%06o read2  %011"PRIo64/*%08o*/" %012"PRIo64" "
                     "(%s)\n", cpu.cycleCnt, cpu.PPR.PSR, cpu.PPR.IC, addr, 
                     M[(addr >> 18) & 077777][addr & 0777777], ctx);
         traceInstruction (0);
@@ -3536,7 +3537,7 @@ int core_read2 (word24 addr, word36 *even, word36 *odd, const char * ctx)
     word36 v;
     LOAD_ACQ_CORE_WORD(v, addr);
     if (v & MEM_LOCKED)
-      sim_warn ("core_read2: even locked %08o locked_addr %08o %c %05o:%06o\n",
+      sim_warn ("core_read2: even locked %011"PRIo64/*%08o*/" locked_addr %011"PRIo64/*%08o*/" %c %05o:%06o\n",
                 addr, cpu.locked_addr, current_running_cpu_idx + 'A',
                 cpu.PPR.PSR, cpu.PPR.IC);
     *even = v & DMASK;
@@ -3548,7 +3549,7 @@ int core_read2 (word24 addr, word36 *even, word36 *odd, const char * ctx)
     UNLOCK_MEM;
 #endif
     sim_debug (DBG_CORE, & cpu_dev,
-               "core_read2 %08o %012"PRIo64" (%s)\n",
+               "core_read2 %011"PRIo64/*%08o*/" %012"PRIo64" (%s)\n",
                 addr - 1, * even, ctx);
 
     // if the even address is OK, the odd will be
@@ -3557,7 +3558,7 @@ int core_read2 (word24 addr, word36 *even, word36 *odd, const char * ctx)
     if (M[(addr >> 18) & 077777][addr & 0777777] & MEM_UNINITIALIZED)
       {
         sim_debug (DBG_WARN, & cpu_dev,
-                   "Unitialized memory accessed at address %08o; "
+                   "Unitialized memory accessed at address %011"PRIo64/*%08o*/"; "
                    "IC is 0%06o:0%06o (%s)\n",
                     addr, cpu.PPR.PSR, cpu.PPR.IC, ctx);
       }
@@ -3565,7 +3566,7 @@ int core_read2 (word24 addr, word36 *even, word36 *odd, const char * ctx)
 #ifndef SPEED
     if (watch_bits [addr])
       {
-        sim_msg ("WATCH [%"PRId64"] %05o:%06o read2  %08o %012"PRIo64" "
+        sim_msg ("WATCH [%"PRId64"] %05o:%06o read2  %011"PRIo64/*%08o*/" %012"PRIo64" "
                     "(%s)\n", cpu.cycleCnt, cpu.PPR.PSR, cpu.PPR.IC, addr,
                     M[(addr >> 18) & 077777][addr & 0777777], ctx);
         traceInstruction (0);
@@ -3574,7 +3575,7 @@ int core_read2 (word24 addr, word36 *even, word36 *odd, const char * ctx)
 #ifdef LOCKLESS
     LOAD_ACQ_CORE_WORD(v, addr);
     if (v & MEM_LOCKED)
-      sim_warn ("core_read2: odd locked %08o locked_addr %08o %c %05o:%06o\n",
+      sim_warn ("core_read2: odd locked %011"PRIo64/*%08o*/" locked_addr %011"PRIo64/*%08o*/" %c %05o:%06o\n",
                 addr, cpu.locked_addr, current_running_cpu_idx + 'A',
                 cpu.PPR.PSR, cpu.PPR.IC);
     *odd = v & DMASK;
@@ -3584,7 +3585,7 @@ int core_read2 (word24 addr, word36 *even, word36 *odd, const char * ctx)
     UNLOCK_MEM;
 #endif
     sim_debug (DBG_CORE, & cpu_dev,
-               "core_read2 %08o %012"PRIo64" (%s)\n",
+               "core_read2 %011"PRIo64/*%08o*/" %012"PRIo64" (%s)\n",
                 addr, * odd, ctx);
 #endif
 #ifdef TR_WORK_MEM
@@ -3596,15 +3597,15 @@ int core_read2 (word24 addr, word36 *even, word36 *odd, const char * ctx)
 #endif
 
 #if !defined(SPEED) || !defined(INLINE_CORE)
-int core_write2 (word24 addr, word36 even, word36 odd, const char * ctx)
+int core_write2 (/*word24*/word36 addr, word36 even, word36 odd, const char * ctx)
   {
     PNL (cpu.portBusy = true;)
     if (addr & 1)
       {
         sim_debug (DBG_MSG, & cpu_dev,
-                   "warning: subtracting 1 from pair at %o in core_write2 "
+                   "warning: subtracting 1 from pair at %"PRIo64/*%o*/" in core_write2 "
                    "(%s)\n", addr, ctx);
-        addr &= (word24)~1; /* make it even a dress, or iron a skirt ;) */
+        addr &= (/*word24*/word36)~1; /* make it even a dress, or iron a skirt ;) */
       }
 #ifdef ISOLTS
     if (cpu.switches.useMap)
@@ -3615,7 +3616,7 @@ int core_write2 (word24 addr, word36 even, word36 odd, const char * ctx)
           {
             doFault (FAULT_STR, fst_str_nea,  __func__);
           }
-        addr = (word24)os + addr % SCBANK;
+        addr = (/*word24*/word36)os + addr % SCBANK;
       }
     else
 #endif
@@ -3636,12 +3637,12 @@ int core_write2 (word24 addr, word36 even, word36 odd, const char * ctx)
 #endif
 
 #ifdef SCUMEM
-    word24 offset;
+    /*word24*/word36 offset;
     uint sci_unit_idx = get_scu_unit_idx (addr, & offset);
     scu [sci_unit_idx].M[offset++] = even & DMASK;
     if (watch_bits [addr])
       {
-        sim_msg ("WATCH [%"PRId64"] %05o:%06o write2 %08o %012"PRIo64" "
+        sim_msg ("WATCH [%"PRId64"] %05o:%06o write2 %011"PRIo64/*%08o*/" %012"PRIo64" "
                     "(%s)\n", cpu.cycleCnt, cpu.PPR.PSR, cpu.PPR.IC, addr,
                     even, ctx);
       }
@@ -3650,7 +3651,7 @@ int core_write2 (word24 addr, word36 even, word36 odd, const char * ctx)
     UNLOCK_MEM;
     if (watch_bits [addr+1])
       {
-        sim_msg ("WATCH [%"PRId64"] %05o:%06o write2 %08o %012"PRIo64" "
+        sim_msg ("WATCH [%"PRId64"] %05o:%06o write2 %011"PRIo64/*%08o*/" %012"PRIo64" "
                     "(%s)\n", cpu.cycleCnt, cpu.PPR.PSR, cpu.PPR.IC, addr+1,
                     odd, ctx);
       }
@@ -3658,7 +3659,7 @@ int core_write2 (word24 addr, word36 even, word36 odd, const char * ctx)
 #ifndef SPEED
     if (watch_bits [addr])
       {
-        sim_msg ("WATCH [%"PRId64"] %05o:%06o write2 %08o %012"PRIo64" "
+        sim_msg ("WATCH [%"PRId64"] %05o:%06o write2 %011"PRIo64/*%08o*/" %012"PRIo64" "
                     "(%s)\n", cpu.cycleCnt, cpu.PPR.PSR, cpu.PPR.IC, addr,
                     even, ctx);
         traceInstruction (0);
@@ -3675,7 +3676,7 @@ int core_write2 (word24 addr, word36 even, word36 odd, const char * ctx)
     UNLOCK_MEM;
 #endif
     sim_debug (DBG_CORE, & cpu_dev,
-               "core_write2 %08o %012"PRIo64" (%s)\n",
+               "core_write2 %011"PRIo64/*%08o*/" %012"PRIo64" (%s)\n",
                 addr - 1, even, ctx);
 
     // If the even address is OK, the odd will be
@@ -3684,7 +3685,7 @@ int core_write2 (word24 addr, word36 even, word36 odd, const char * ctx)
 #ifndef SPEED
     if (watch_bits [addr])
       {
-        sim_msg ("WATCH [%"PRId64"] %05o:%06o write2 %08o %012"PRIo64" "
+        sim_msg ("WATCH [%"PRId64"] %05o:%06o write2 %011"PRIo64/*%08o*/" %012"PRIo64" "
                     "(%s)\n", cpu.cycleCnt, cpu.PPR.PSR, cpu.PPR.IC, addr,
                     odd, ctx);
         traceInstruction (0);
@@ -3704,7 +3705,7 @@ int core_write2 (word24 addr, word36 even, word36 odd, const char * ctx)
 #endif
     PNL (trackport (addr - 1, even));
     sim_debug (DBG_CORE, & cpu_dev,
-               "core_write2 %08o %012"PRIo64" (%s)\n",
+               "core_write2 %011"PRIo64/*%08o*/" %012"PRIo64" (%s)\n",
                 addr, odd, ctx);
     return 0;
   }
index 7f35295..ab1d9a7 100644 (file)
@@ -1732,7 +1732,7 @@ typedef struct
      bool is_FFV;
 #endif
 
-    word24 iefpFinalAddress;
+    /*word24*/word36 iefpFinalAddress;
     word36 CY;              // C(Y) operand data from memory
     word36 Ypair[2];        // 2-words
     word36 Yblock8[8];      // 8-words
@@ -2188,16 +2188,16 @@ static inline int core_write2 (word24 addr, word36 even, word36 odd,
     return 0;
   }
 #else  // defined(SPEED) && defined(INLINE_CORE)
-int core_read (word24 addr, word36 *data, const char * ctx);
-int core_write (word24 addr, word36 data, const char * ctx);
-int core_write_zone (word24 addr, word36 data, const char * ctx);
-int core_read2 (word24 addr, word36 *even, word36 *odd, const char * ctx);
-int core_write2 (word24 addr, word36 even, word36 odd, const char * ctx);
+int core_read (/*word24*/word36 addr, word36 *data, const char * ctx);
+int core_write (/*word24*/word36 addr, word36 data, const char * ctx);
+int core_write_zone (/*word24*/word36 addr, word36 data, const char * ctx);
+int core_read2 (/*word24*/word36 addr, word36 *even, word36 *odd, const char * ctx);
+int core_write2 (/*word24*/word36 addr, word36 even, word36 odd, const char * ctx);
 #endif // defined(SPEED) && defined(INLINE_CORE)
 
 #ifdef LOCKLESS
-int core_read_lock (word24 addr, word36 *data, const char * ctx);
-int core_write_unlock (word24 addr, word36 data, const char * ctx);
+int core_read_lock (/*word24*/word36 addr, word36 *data, const char * ctx);
+int core_write_unlock (/*word24*/word36 addr, word36 data, const char * ctx);
 int core_unlock_all();
 
 #define DEADLOCK_DETECT          0x40000000U
index ff0e47d..efd3d13 100644 (file)
@@ -100,7 +100,7 @@ B29:;
                cpu.TPR.TRR = cpu.PPR.PRR;
                 cpu.iefpFinalAddress = do_append_cycle (cyctyp, result, 1);
                 sim_debug (DBG_APPENDING | DBG_FINAL, & cpu_dev, 
-                           "Read (Actual) Read:  bar iefpFinalAddress=%08o  "
+                           "Read (Actual) Read:  bar iefpFinalAddress=%011"PRIo64/*%08o*/"  "
                            "readData=%012"PRIo64"\n",
                            cpu.iefpFinalAddress, * result);
                 HDBGMRead (cpu.iefpFinalAddress, * result);
@@ -114,7 +114,7 @@ B29:;
                 if (cpu.PPR.PSR != 061 && cpu.PPR.IC != 0307)
                   {
                     sim_debug (DBG_APPENDING | DBG_FINAL, & cpu_dev,
-                               "Read (Actual) Read:  iefpFinalAddress=%08o  "
+                               "Read (Actual) Read:  iefpFinalAddress=%011"PRIo64/*%08o*/"  "
                                "readData=%012"PRIo64"\n",
                                cpu.iefpFinalAddress, * result);
                     HDBGMRead (cpu.iefpFinalAddress, * result);
@@ -197,7 +197,7 @@ B29:;
                     for (uint i = 0; i < 2; i ++)
                      sim_debug (DBG_APPENDING | DBG_FINAL, & cpu_dev,
                                 "Read2 (Actual) Read:  bar iefpFinalAddress="
-                                "%08o  readData=%012"PRIo64"\n", 
+                                "%011"PRIo64/*%08o*/"  readData=%012"PRIo64"\n", 
                                 cpu.iefpFinalAddress + i, result [i]);
                   }
                 HDBGMRead (cpu.iefpFinalAddress, * result);
@@ -211,7 +211,7 @@ B29:;
                   {
                     for (uint i = 0; i < 2; i ++)
                       sim_debug (DBG_APPENDING | DBG_FINAL, & cpu_dev, 
-                                 "Read2 (Actual) Read:  iefpFinalAddress=%08o"
+                                 "Read2 (Actual) Read:  iefpFinalAddress=%011"PRIo64/*%08o*/""
                                  "  readData=%012"PRIo64"\n",
                                  cpu.iefpFinalAddress + i, result [i]);
                   }
@@ -296,7 +296,7 @@ B29:;
                     for (uint i = 0; i < 8; i ++)
                      sim_debug (DBG_APPENDING | DBG_FINAL, & cpu_dev,
                                 "Read8 (Actual) Read:  bar iefpFinalAddress="
-                                "%08o  readData=%012"PRIo64"\n",
+                                "%011"PRIo64/*%08o*/"  readData=%012"PRIo64"\n",
                                 cpu.iefpFinalAddress + i, result [i]);
                   }
 #ifdef HDBG
@@ -317,7 +317,7 @@ B29:;
                         for (uint i = 0; i < 8; i ++)
                           sim_debug (DBG_APPENDING | DBG_FINAL, & cpu_dev,
                                      "Read8 (Actual) Read:  iefpFinalAddress="
-                                     "%08o  readData=%012"PRIo64"\n",
+                                     "%011"PRIo64/*%08o*/"  readData=%012"PRIo64"\n",
                                      cpu.iefpFinalAddress + i, result [i]);
                       }
 #ifdef HDBG
@@ -417,7 +417,7 @@ B29:;
                     for (uint i = 0; i < PGSZ; i ++)
                      sim_debug (DBG_APPENDING | DBG_FINAL, & cpu_dev, 
                                 "ReadPage (Actual) Read:  bar iefpFinalAddress="
-                                "%08o  readData=%012"PRIo64"\n",
+                                "%011"PRIo64/*%08o*/"  readData=%012"PRIo64"\n",
                                 cpu.iefpFinalAddress + i, result [i]);
                   }
 #ifdef HDBG
@@ -439,7 +439,7 @@ B29:;
                         for (uint i = 0; i < PGSZ; i ++)
                           sim_debug (DBG_APPENDING | DBG_FINAL, & cpu_dev,
                                      "ReadPage (Actual) Read:  iefpFinalAddress"
-                                     "=%08o  readData=%012"PRIo64"\n", 
+                                     "=%011"PRIo64/*%08o*/"  readData=%012"PRIo64"\n", 
                                      cpu.iefpFinalAddress + i, result [i]);
                       }
 #ifdef HDBG
@@ -518,7 +518,7 @@ B29:
                cpu.TPR.TRR = cpu.PPR.PRR;
                 cpu.iefpFinalAddress = do_append_cycle (cyctyp, & data, 1);
                 sim_debug (DBG_APPENDING | DBG_FINAL, & cpu_dev,
-                           "Write(Actual) Write: bar iefpFinalAddress=%08o "
+                           "Write(Actual) Write: bar iefpFinalAddress=%011"PRIo64/*%08o*/" "
                            "writeData=%012"PRIo64"\n",
                            cpu.iefpFinalAddress, data);
                 HDBGMWrite (cpu.iefpFinalAddress, data);
@@ -528,7 +528,7 @@ B29:
               {
                 cpu.iefpFinalAddress = do_append_cycle (cyctyp, & data, 1);
                 sim_debug (DBG_APPENDING | DBG_FINAL, & cpu_dev,
-                           "Write(Actual) Write: iefpFinalAddress=%08o "
+                           "Write(Actual) Write: iefpFinalAddress=%011"PRIo64/*%08o*/" "
                            "writeData=%012"PRIo64"\n",
                            cpu.iefpFinalAddress, data);
                 HDBGMWrite (cpu.iefpFinalAddress, data);
@@ -592,9 +592,9 @@ B29:
                cpu.TPR.TRR = cpu.PPR.PRR;
                 cpu.iefpFinalAddress = do_append_cycle (cyctyp, data, 2);
                 sim_debug (DBG_APPENDING | DBG_FINAL, & cpu_dev,
-                           "Write2 (Actual) Write: bar iefpFinalAddress=%08o "
+                           "Write2 (Actual) Write: bar iefpFinalAddress=%011"PRIo64/*%08o*/" "
                            "writeData=%012"PRIo64" %012"PRIo64"\n", 
-                           address, data [0], data [1]);
+                           cpu.iefpFinalAddress, data [0], data [1]); // NICK BUGFIX
                 HDBGMWrite (cpu.iefpFinalAddress, data[0]);
                 HDBGMWrite (cpu.iefpFinalAddress+1, data[1]);
               }
@@ -602,9 +602,9 @@ B29:
               {
                 cpu.iefpFinalAddress = do_append_cycle (cyctyp, data, 2);
                 sim_debug (DBG_APPENDING | DBG_FINAL, & cpu_dev,
-                           "Write2 (Actual) Write: iefpFinalAddress=%08o "
+                           "Write2 (Actual) Write: iefpFinalAddress=%011"PRIo64/*%08o*/" "
                            "writeData=%012"PRIo64" %012"PRIo64"\n", 
-                           address, data [0], data [1]);
+                           cpu.iefpFinalAddress, data [0], data [1]); // NICK BUGFIX
                 HDBGMWrite (cpu.iefpFinalAddress, data[0]);
                 HDBGMWrite (cpu.iefpFinalAddress+1, data[1]);
               }
@@ -664,7 +664,7 @@ B29:
                                                         1);
                 sim_debug (DBG_APPENDING | DBG_FINAL, & cpu_dev,
                            "Write8(Actual) Write: bar iefpFinalAddress="
-                           "%08o writeData=%012"PRIo64"\n",
+                           "%011"PRIo64/*%08o*/" writeData=%012"PRIo64"\n",
                            cpu.iefpFinalAddress, data);
                 HDBGMWrite (cpu.iefpFinalAddress, data);
                 return;
@@ -674,7 +674,7 @@ B29:
                 cpu.iefpFinalAddress = do_append_cycle (APU_DATA_STORE, & data, 
                                                        1);
                 sim_debug (DBG_APPENDING | DBG_FINAL, & cpu_dev,
-                           "Write(Actual) Write: iefpFinalAddress=%08o "
+                           "Write(Actual) Write: iefpFinalAddress=%011"PRIo64/*%08o*/" "
                            "writeData=%012"PRIo64"\n",
                            cpu.iefpFinalAddress, data);
                 HDBGMWrite (cpu.iefpFinalAddress, data);
@@ -757,7 +757,7 @@ B29:
                     for (uint i = 0; i < 8; i ++)
                       sim_debug (DBG_APPENDING | DBG_FINAL, & cpu_dev,
                                  "Write8(Actual) Write: bar iefpFinalAddress="
-                                 "%08o writeData=%012"PRIo64"\n",
+                                 "%011"PRIo64/*%08o*/" writeData=%012"PRIo64"\n",
                                  cpu.iefpFinalAddress + i, data [i]);
                   }
 #ifdef HDBG
@@ -775,7 +775,7 @@ B29:
                   {
                     for (uint i = 0; i < 8; i ++)
                       sim_debug (DBG_APPENDING | DBG_FINAL, & cpu_dev,
-                                 "Write8(Actual) Write: iefpFinalAddress=%08o "
+                                 "Write8(Actual) Write: iefpFinalAddress=%011"PRIo64/*%08o*/" "
                                  "writeData=%012"PRIo64"\n",
                                  cpu.iefpFinalAddress + i, data [i]);
                   }
@@ -886,7 +886,7 @@ B29:
                     for (uint i = 0; i < PGSZ; i ++)
                       sim_debug (DBG_APPENDING | DBG_FINAL, & cpu_dev,
                                  "WritePage(Actual) Write: bar "
-                                 "iefpFinalAddress=%08o writeData=%012"PRIo64
+                                 "iefpFinalAddress=%011"PRIo64/*%08o*/" writeData=%012"PRIo64
                                  "\n",
                                  cpu.iefpFinalAddress + i, data [i]);
                   }
@@ -901,7 +901,7 @@ B29:
                     for (uint i = 0; i < PGSZ; i ++)
                       sim_debug (DBG_APPENDING | DBG_FINAL, & cpu_dev,
                                  "WritePage(Actual) Write: iefpFinalAddress="
-                                 "%08o writeData=%012"PRIo64"\n",
+                                 "%011"PRIo64/*%08o*/" writeData=%012"PRIo64"\n",
                                  cpu.iefpFinalAddress + i, data [i]);
                   }
 #ifdef HDBG
index 76e78c6..aca3657 100644 (file)
@@ -2609,7 +2609,6 @@ static t_stat doInstruction (void)
 #endif
 #endif // PANEL
 
- //printf("opcode10 %03o\n", opcode10);
     switch (opcode10)
       {
 
@@ -9611,7 +9610,7 @@ static int emCall (void)
             if (i->address == 16)
               addr = cpu.rA >> 18;
             else // 21
-              addr = cpu.rA >> 12;
+              addr = cpu.rA; // >> 12;
             word36 chunk = 0;
             int i;
             bool is_escape = false;
@@ -9620,8 +9619,10 @@ static int emCall (void)
             for (i = 0; cnt < maxlen; i ++)
             {
                 // fetch char
-                if (i % 4 == 0)
-                    chunk = M[addr ++];
+                if (i % 4 == 0) {
+                    chunk = M[(addr >> 18) & 077777][addr & 0777777];
+                    addr++;
+                }
                 word36 wch = chunk >> (9 * 3);
                 chunk = (chunk << 9) & DMASK;
                 char ch = (char) (wch & 0x7f);
@@ -9682,6 +9683,10 @@ static int emCall (void)
 
         // case 21 defined above
 
+ case 22:
+  ;
+  extern jmp_buf exit_emulation;
+  longjmp(exit_emulation, 1);
     }
     return 0;
 }
index 552a023..d4d432e 100644 (file)
@@ -121,7 +121,7 @@ void get_acc_string(uint64_t *acc_string, char *buf, int 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[i] = (char)(acc_string[j >> 2] >> shifts[j & 3]);
   buf[len] = 0;
 }
 
index e7e759e..26e64b8 100644 (file)
@@ -121,7 +121,7 @@ void get_acc_string(uint64_t *acc_string, char *buf, int 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[i] = (char)(acc_string[j >> 2] >> shifts[j & 3]);
   buf[len] = 0;
 }
 
index e7a4983..f956aff 100644 (file)
@@ -1,4 +1,5 @@
 #include <fcntl.h>
+#include <setjmp.h>
 #include <stdbool.h>
 #include <stdint.h>
 #include <stdio.h>
@@ -15,6 +16,7 @@
 #include "object_map.h"
 #include "pointer.h"
 #include "rassert.h"
+#include "stack_frame.h"
 #include "stack_header.h"
 
 struct arg_list {
@@ -63,18 +65,15 @@ struct loaded_segment *loaded_segment_xref[N_SEGMENT];
 int next_segment;
 
 int linkage_segment;
+int next_linkage_offset;
 struct packed_pointer *lot;
 struct packed_pointer *isot;
 
 int stack_segment;
+int next_stack_offset;
 struct stack_header *stack_header;
 
-#define STACK_OFFSET ((int)(sizeof(struct 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;
+jmp_buf exit_emulation;
 
 int allocate_segment(void) {
   rassert(next_segment < N_SEGMENT);
@@ -122,6 +121,15 @@ int allocate_linkage(int length, bool even) {
   return offset;
 }
 
+int allocate_stack(int length, bool even) {
+  if (even)
+    next_stack_offset = (next_stack_offset + 1) & ~1;
+  rassert(next_stack_offset + length <= 01000000);
+  int offset = next_stack_offset;
+  next_stack_offset += length;
+  return offset;
+}
+
 const char *xlate_segment(const char *name) {
   // search for segment in path
   int path_index;
@@ -172,6 +180,7 @@ struct loaded_segment *load_segment(const char *name) {
   rassert(p->name);
 
   p->segment = allocate_segment();
+  printf("loading segment name %s into segment %06o\n", name, p->segment);
   loaded_segment_xref[p->segment] = p;
 
   // search for segment in path
@@ -237,12 +246,6 @@ found_bitcount:
     object_map->linkage_length >=
       sizeof(struct linkage_header) / sizeof(uint64_t)
   );
-  rassert(
-    next_linkage_offset +
-      object_map->linkage_length +
-      object_map->static_length <=
-      01000000
-  );
 
   // copy and fill in linkage section
   p->linkage_offset = allocate_linkage(object_map->linkage_length, true);
@@ -290,7 +293,7 @@ void get_acc_string(uint64_t *acc_string, char *buf, int 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[i] = (char)(acc_string[j >> 2] >> shifts[j & 3]);
   buf[len] = 0;
 }
 
@@ -422,7 +425,6 @@ bool snap_link(void) {
     type_pair->type >= LINK_SELF_BASE &&
       type_pair->type <= LINK_CREATE_IF_NOT_FOUND
   );
-  printf("link type %s\n", link_type_names[type_pair->type - 1]);
 
   // process link by type
   switch (type_pair->type) {
@@ -442,19 +444,23 @@ bool snap_link(void) {
         sizeof(offsetname)
       );
 
-      printf(
-        "link target %s$%s + %06o\n",
-        segname,
-        offsetname,
-        exp_word->expression
-      );
-
       struct loaded_segment *q = load_segment(xlate_segment(segname));
       *link = its_pointer(
         q->segment,
         find_entry(q, segname, offsetname, false)
       );
       link->modifier1 = virgin_link->modifier;
+
+      printf(
+        "snap link %06o:%06o -> %s$%s + %06o -> %06o:%06o\n",
+        (int)cpu.TPR.TSR,
+        (int)cpu.TPR.CA,
+        segname,
+        offsetname,
+        (int)exp_word->expression,
+        (int)link->segment,
+        (int)link->address
+      );
     }
     break;
   default:
@@ -485,6 +491,7 @@ int main(int argc, char **argv) {
 
   // initialize CPU
   cpu_reset_unit_idx(0, false);
+  set_addr_mode(APPEND_mode);
 
   // initialize memory
   uint64_t *null_segment = mmap(
@@ -502,128 +509,176 @@ int main(int argc, char **argv) {
 
   // 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;
+  //next_linkage_offset = 0;
+
+  // create stack segment
+  stack_segment = scratch_segment();
+  next_stack_offset = sizeof(struct stack_header) / sizeof(uint64_t);
+  stack_header = (struct stack_header *)M[stack_segment];
+
+  // allocate LOT and ISOT
+  stack_header->max_lot_size = N_SEGMENT;
+  int lot_offset = allocate_linkage(N_SEGMENT, false);
+  lot = (struct packed_pointer *)(M[linkage_segment] + lot_offset);
+  stack_header->lot_ptr = its_pointer(linkage_segment, lot_offset);
+  int isot_offset = allocate_linkage(N_SEGMENT, false);
+  isot = (struct packed_pointer *)(M[linkage_segment] + isot_offset);
+  stack_header->isot_ptr = its_pointer(linkage_segment, isot_offset);
+
+  // load pl1 operators
+  struct loaded_segment *p = load_segment(xlate_segment("pl1_operators_"));
+  int operator_table_offset = find_entry(
+    p,
+    "pl1_operators_",
+    "operator_table",
+    false
+  );
+  stack_header->pl1_operators_ptr = its_pointer(
+    p->segment,
+    operator_table_offset
+  );
+  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)
+  );
 
-  // save command line
-  int arg_list_offset = allocate_linkage(6 + n_args * 4, true);
+  // create first stack frame
+  int stack_frame_offset = allocate_stack(
+    sizeof(struct stack_frame) / sizeof(uint64_t),
+    true
+  );
+  struct stack_frame *stack_frame = (struct stack_frame *)(
+    M[stack_segment] + stack_frame_offset
+  );
+  stack_header->stack_begin_ptr = its_pointer(
+    stack_segment,
+    stack_frame_offset
+  );
 
+  // append command line to first stack frame
+  int arg_list_offset = allocate_stack(6 + n_args * 4, true);
   struct arg_list *arg_list = (struct arg_list *)(
-    M[linkage_segment] + arg_list_offset
+    M[stack_segment] + arg_list_offset
   );
-  arg_list->arg_count = n_args + 1;
-  arg_list->code = 4;
-  arg_list->desc_count = n_args;
+  //arg_list->arg_count = n_args + 1;
+  //arg_list->code = 4;
+  //arg_list->desc_count = n_args;
 
   for (int i = 0; i < n_args; ++i) {
-    int arg_offset = allocate_linkage((strlen(args[i]) + 3) >> 2, false);
-    arg_list->args[i] = its_pointer(linkage_segment, arg_offset);
+    int arg_offset = allocate_stack((strlen(args[i]) + 3) >> 2, false);
+    arg_list->args[i] = its_pointer(stack_segment, arg_offset);
 
-    uint64_t *arg = (uint64_t *)(M[linkage_segment] + arg_offset);
+    uint64_t *arg = (uint64_t *)(M[stack_segment] + arg_offset);
     static int shifts[4] = {27, 18, 9, 0};
     for (int j = 0; args[i][j]; ++j)
       arg[j >> 2] |= (uint64_t)args[i][j] << shifts[j & 3];
 
-    int arg_desc_offset = allocate_linkage(
+    int arg_desc_offset = allocate_stack(
       sizeof(struct arg_desc) / sizeof(uint64_t),
       false
     );
     arg_list->args[n_args + 1 + i] =
-      its_pointer(linkage_segment, arg_desc_offset);
+      its_pointer(stack_segment, arg_desc_offset);
 
     struct arg_desc *arg_desc = (struct arg_desc *)(
-      M[linkage_segment] + arg_desc_offset
+      M[stack_segment] + arg_desc_offset
     );
     arg_desc->flag = 1; // version 2 descriptor
     arg_desc->type = 21; // character string
-    arg_desc->packed = 1;
+    arg_desc->packed = 0;
     arg_desc->number_dims = 0;
     arg_desc->size = strlen(args[i]);
   }
 
-  int result_offset = allocate_linkage(0x100, false); // 1 kbyte of output
-  arg_list->args[n_args] = its_pointer(linkage_segment, result_offset);
+  int result_offset = allocate_stack(0x101, false); // 1 kbyte of output
+  arg_list->args[n_args] = its_pointer(stack_segment, result_offset + 1);
 
-  int arg_desc_offset = allocate_linkage(
+  int arg_desc_offset = allocate_stack(
     sizeof(struct arg_desc) / sizeof(uint64_t),
     false
   );
   arg_list->args[n_args * 2 + 1] =
-    its_pointer(linkage_segment, arg_desc_offset);
+    its_pointer(stack_segment, arg_desc_offset);
 
   struct arg_desc *arg_desc = (struct arg_desc *)(
-    M[linkage_segment] + arg_desc_offset
+    M[stack_segment] + arg_desc_offset
   );
   arg_desc->flag = 1; // version 2 descriptor
   arg_desc->type = 22; // varying character string
-  arg_desc->packed = 1;
+  arg_desc->packed = 0;
   arg_desc->number_dims = 0;
   arg_desc->size = 0x400; // 1 kbyte of output
 
-  // 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(xlate_segment("pl1_operators_"));
-  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->stack_end_ptr = its_pointer(
+    stack_segment,
+    allocate_stack(0, true)
   );
-  stack_header->no_pop_op_ptr = its_pointer(
-    p->segment,
-    find_entry(p, "pl1_operators_", "alm_return_no_pop", false)
+
+  // create calling stub
+  int calling_stub_offset = allocate_linkage(2, false);
+  uint64_t *calling_stub = (uint64_t *)(
+    M[linkage_segment] + calling_stub_offset
   );
-  stack_header->entry_op_ptr = its_pointer(
-    p->segment,
-    find_entry(p, "pl1_operators_", "alm_entry", false)
+  stack_frame->return_ptr = its_pointer(
+    linkage_segment,
+    0 // will be overwritten by call_ext_out
   );
+  calling_stub[0] = 0000622700100L; // tsx0 pr0|402 call_ext_out_desc
+  calling_stub[1] = 0000026420400L; // emcall exit_emulation
+
+  cpu.rA = (word36)(n_args + 1) << 19;
+  cpu.rX[1] = arg_list_offset;
+
+  cpu.PR[0].RNR = 3;
+  cpu.PR[0].SNR = p->segment;
+  cpu.PR[0].WORDNO = operator_table_offset;
 
-  // set up registers
   struct loaded_segment *q = load_segment(xlate_segment(entry_segname));
-  set_addr_mode(APPEND_mode);
+  cpu.PR[2].RNR = 3;
+  cpu.PR[2].SNR = q->segment;
+  cpu.PR[2].WORDNO = find_entry(q, entry_segname, entry_name, true);
+
+  cpu.PR[6].RNR = 3;
+  cpu.PR[6].SNR = stack_segment;
+  cpu.PR[6].WORDNO = stack_frame_offset;
 
-  // ic (instruction counter)
-  cpu.PPR.PRR = 3; // ring
-  cpu.PPR.PSR = q->segment; // segment
+  cpu.PPR.PRR = 3;
+  cpu.PPR.PSR = linkage_segment;
   cpu.PPR.P = 0; // privilege
-  cpu.PPR.IC = find_entry(q, entry_segname, entry_name, true); // address
-
-  // ap (argument pointer)
-  cpu.PR[0].RNR = 3; // ring
-  cpu.PR[0].SNR = linkage_segment; // segment
-  cpu.PR[0].WORDNO = arg_list_offset; // 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
+  cpu.PPR.IC = calling_stub_offset;
 
   // enter simulator
-  sim_instr();
+  if (setjmp(exit_emulation) == 0) {
+    sim_instr();
+    abort();
+  }
+
+  // print result string
+  char text[0x401];
+  uint64_t *result = (uint64_t *)(M[stack_segment] + result_offset);
+  int len = (int)(*result++ & 0777777);
+  rassert(len < sizeof(result));
+  static int shifts[4] = {27, 18, 9, 0};
+  for (int i = 0; i < len; ++i)
+    text[i] = (char)(result[i >> 2] >> shifts[i & 3]);
+  text[len] = 0;
+  printf("%s\n", text);
 
   return 0;
 }
diff --git a/pl1/stack_frame.incl.pl1 b/pl1/stack_frame.incl.pl1
new file mode 100644 (file)
index 0000000..0aee99d
--- /dev/null
@@ -0,0 +1,91 @@
+/*     BEGIN INCLUDE FILE ... stack_frame.incl.pl1 ... */
+
+/* format: off */
+
+/* Modified: 16 Dec 1977, D. Levin - to add fio_ps_ptr and pl1_ps_ptr */
+/* Modified:  3 Feb 1978, P. Krupp - to add run_unit_manager bit & main_proc bit */
+/* Modified: 21 March 1978, D. Levin - change fio_ps_ptr to support_ptr */
+/* Modified: 03/01/84, S. Herbst - Added RETURN_PTR_MASK */
+
+
+/****^  HISTORY COMMENTS:
+  1) change(86-09-15,Kissel), approve(86-09-15,MCR7473),
+     audit(86-10-01,Fawcett), install(86-11-03,MR12.0-1206):
+     Modified to add constants for the translator_id field in the stack_frame
+     structure.
+                                                   END HISTORY COMMENTS */
+
+
+dcl RETURN_PTR_MASK bit (72) int static options (constant)  /* mask to be AND'd with stack_frame.return_ptr */
+       init ("777777777777777777000000"b3);            /* when copying, to ignore bits that a call fills */
+                                               /* with indicators (nonzero for Fortran hexfp caller) */
+                       /* say: unspec(ptr) = unspec(stack_frame.return_ptr) & RETURN_PTR_MASK; */
+
+dcl TRANSLATOR_ID_PL1V2 bit (18) internal static options (constant) init ("000000"b3);
+dcl TRANSLATOR_ID_ALM bit (18) internal static options (constant) init ("000001"b3);
+dcl TRANSLATOR_ID_PL1V1 bit (18) internal static options (constant) init ("000002"b3);
+dcl TRANSLATOR_ID_SIGNAL_CALLER bit (18) internal static options (constant) init ("000003"b3);
+dcl TRANSLATOR_ID_SIGNALLER bit (18) internal static options (constant) init ("000004"b3);
+
+
+dcl  sp pointer;                                       /* pointer to beginning of stack frame */
+
+dcl  stack_frame_min_length fixed bin static init(48);
+
+
+dcl 1 stack_frame based(sp) aligned,
+    2 pointer_registers(0 : 7) ptr,
+    2 prev_sp pointer,
+    2 next_sp pointer,
+    2 return_ptr pointer,
+    2 entry_ptr pointer,
+    2 operator_and_lp_ptr ptr,                 /* serves as both */
+    2 arg_ptr pointer,
+    2 static_ptr ptr unaligned,
+    2 support_ptr ptr unal, /* only used by fortran I/O */
+    2 on_unit_relp1 bit(18) unaligned,
+    2 on_unit_relp2 bit(18) unaligned,
+    2 translator_id bit(18) unaligned,                 /* Translator ID (see constants above)
+                                                  0 => PL/I version II
+                                                  1 => ALM
+                                                  2 => PL/I version I   
+                                                  3 => signal caller frame
+                                                  4 => signaller frame */
+    2 operator_return_offset bit(18) unaligned,
+    2 x(0: 7) bit(18) unaligned,                       /* index registers */
+    2 a bit(36),                                       /* accumulator */
+    2 q bit(36),                                       /* q-register */
+    2 e bit(36),                                       /* exponent */
+    2 timer bit(27) unaligned,                         /* timer */
+    2 pad bit(6) unaligned,
+    2 ring_alarm_reg bit(3) unaligned;
+
+
+dcl 1 stack_frame_flags based(sp) aligned,
+    2 pad(0 : 7) bit(72),                              /* skip over prs */
+    2 xx0 bit(22) unal,
+    2 main_proc bit(1) unal,                           /* on if frame belongs to a main procedure */
+    2 run_unit_manager bit(1) unal,                    /* on if frame belongs to run unit manager */
+    2 signal bit(1) unal,                              /* on if frame belongs to logical signal_ */
+    2 crawl_out bit(1) unal,                           /* on if this is a signal caller frame */
+    2 signaller bit(1) unal,                           /* on if next frame is signaller's */
+    2 link_trap bit(1) unal,                           /* on if this frame was made by the linker */
+    2 support bit(1) unal,                             /* on if frame belongs to a support proc */
+    2 condition bit(1) unal,                           /* on if condition established in this frame */
+    2 xx0a bit(6) unal,
+    2 xx1 fixed bin,
+    2 xx2 fixed bin,
+    2 xx3 bit(25) unal,
+    2 old_crawl_out bit (1) unal,                      /* on if this is a signal caller frame */
+    2 old_signaller bit(1) unal,                       /* on if next frame is signaller's */
+    2 xx3a bit(9) unaligned,
+    2 xx4(9) bit(72) aligned,
+    2 v2_pl1_op_ret_base ptr,                          /* When a V2 PL/I program calls an operator the
+                                               *  operator puts a pointer to the base of
+                                               *  the calling procedure here. (text base ptr)  */
+    2 xx5 bit(72) aligned,
+    2 pl1_ps_ptr ptr;                          /* ptr to ps for this frame; also used by fio. */
+
+/* format: on */
+
+/*     END INCLUDE FILE ... stack_frame.incl.pl1 */
diff --git a/stack_frame.h b/stack_frame.h
new file mode 100644 (file)
index 0000000..dd91579
--- /dev/null
@@ -0,0 +1,172 @@
+#ifndef _STACK_FRAME_H
+#define _STACK_FRAME_H
+
+#include "pointer.h"
+
+// see pl1/stack_frame.incl.pl1
+
+// dcl RETURN_PTR_MASK bit (72) int static options (constant) /* mask to be AND'd with stack_frame.return_ptr */
+// init ("777777777777777777000000"b3); /* when copying, to ignore bits that a call fills */
+// /* with indicators (nonzero for Fortran hexfp caller) */
+// /* say: unspec(ptr) = unspec(stack_frame.return_ptr) & RETURN_PTR_MASK; */
+#define RETURN_PTR_MASK 0777777777777777777000000L
+
+enum {
+  // dcl TRANSLATOR_ID_PL1V2 bit (18) internal static options (constant) init ("000000"b3);
+  TRANSLATOR_ID_PL1V2 = 0,
+
+  // dcl TRANSLATOR_ID_ALM bit (18) internal static options (constant) init ("000001"b3);
+  TRANSLATOR_ID_ALM = 1,
+
+  // dcl TRANSLATOR_ID_PL1V1 bit (18) internal static options (constant) init ("000002"b3);
+  TRANSLATOR_ID_PL1V1 = 2,
+
+  // dcl TRANSLATOR_ID_SIGNAL_CALLER bit (18) internal static options (constant) init ("000003"b3);
+  TRANSLATOR_ID_SIGNAL_CALLER = 3,
+
+  // dcl TRANSLATOR_ID_SIGNALLER bit (18) internal static options (constant) init ("000004"b3);
+  TRANSLATOR_ID_SIGNALLER = 4
+};
+
+// dcl sp pointer; /* pointer to beginning of stack frame */
+
+// dcl stack_frame_min_length fixed bin static init(48);
+
+// dcl 1 stack_frame based(sp) aligned,
+struct stack_frame {
+  // 2 pointer_registers(0 : 7) ptr,
+  struct its_pointer pointer_registers[8];
+
+  // 2 prev_sp pointer,
+  struct its_pointer prev_sp;
+
+  // 2 next_sp pointer,
+  struct its_pointer next_sp;
+
+  // 2 return_ptr pointer,
+  struct its_pointer return_ptr;
+
+  // 2 entry_ptr pointer,
+  struct its_pointer entry_ptr;
+
+  // 2 operator_and_lp_ptr ptr, /* serves as both */
+  struct its_pointer operator_and_lp_ptr;
+
+  // 2 arg_ptr pointer,
+  struct its_pointer arg_ptr;
+
+  // 2 static_ptr ptr unaligned,
+  struct its_pointer static_ptr;
+
+  // 2 support_ptr ptr unal, /* only used by fortran I/O */
+  struct packed_pointer support_ptr;
+
+  // 2 on_unit_relp1 bit(18) unaligned,
+  // 2 on_unit_relp2 bit(18) unaligned,
+  uint64_t on_unit_relp2 : 18;
+  uint64_t on_unit_relp1 : 18;
+  uint64_t dummy0 : 28;
+
+  // 2 translator_id bit(18) unaligned, /* Translator ID (see constants above)
+  // 0 => PL/I version II
+  // 1 => ALM
+  // 2 => PL/I version I 
+  // 3 => signal caller frame
+  // 4 => signaller frame */
+  // 2 operator_return_offset bit(18) unaligned,
+  uint64_t operator_return_offset : 18;
+  uint64_t translator_id : 18;
+  uint64_t dummy1 : 28;
+
+  // 2 x(0: 7) bit(18) unaligned, /* index registers */
+  uint64_t x1 : 18;
+  uint64_t x0 : 18;
+  uint64_t dummy2 : 28;
+  uint64_t x3 : 18;
+  uint64_t x2 : 18;
+  uint64_t dummy3 : 28;
+  uint64_t x5 : 18;
+  uint64_t x4 : 18;
+  uint64_t dummy4 : 28;
+  uint64_t x7 : 18;
+  uint64_t x6 : 18;
+  uint64_t dummy5 : 28;
+
+  // 2 a bit(36), /* accumulator */
+  uint64_t a;
+
+  // 2 q bit(36), /* q-register */
+  uint64_t q;
+
+  // 2 e bit(36), /* exponent */
+  uint64_t e;
+
+  // 2 timer bit(27) unaligned, /* timer */
+  // 2 pad bit(6) unaligned,
+  // 2 ring_alarm_reg bit(3) unaligned;
+  uint64_t ring_alarm_reg : 3;
+  uint64_t pad : 6;
+  uint64_t timer : 27;
+  uint64_t dummy6 : 28;
+};
+
+// dcl 1 stack_frame_flags based(sp) aligned,
+struct stack_frame_flags {
+  // 2 pad(0 : 7) bit(72), /* skip over prs */
+  uint64_t pad[16];
+
+  // 2 xx0 bit(22) unal,
+  // 2 main_proc bit(1) unal, /* on if frame belongs to a main procedure */
+  // 2 run_unit_manager bit(1) unal, /* on if frame belongs to run unit manager */
+  // 2 signal bit(1) unal, /* on if frame belongs to logical signal_ */
+  // 2 crawl_out bit(1) unal, /* on if this is a signal caller frame */
+  // 2 signaller bit(1) unal, /* on if next frame is signaller's */
+  // 2 link_trap bit(1) unal, /* on if this frame was made by the linker */
+  // 2 support bit(1) unal, /* on if frame belongs to a support proc */
+  // 2 condition bit(1) unal, /* on if condition established in this frame */
+  // 2 xx0a bit(6) unal,
+  uint64_t xx0a : 6;
+  uint64_t condition : 1;
+  uint64_t support : 1;
+  uint64_t link_trap : 1;
+  uint64_t signaller : 1;
+  uint64_t crawl_out : 1;
+  uint64_t signal : 1;
+  uint64_t run_unit_manager : 1;
+  uint64_t main_proc : 1;
+  uint64_t xx0 : 22;
+  uint64_t dummy0 : 28;
+
+  // 2 xx1 fixed bin,
+  // 2 xx2 fixed bin,
+  int64_t xx2 : 18;
+  uint64_t dummy1 : 46;
+  int64_t xx1 : 18;
+  uint64_t dummy2 : 46;
+
+  // 2 xx3 bit(25) unal,
+  // 2 old_crawl_out bit (1) unal, /* on if this is a signal caller frame */
+  // 2 old_signaller bit(1) unal, /* on if next frame is signaller's */
+  // 2 xx3a bit(9) unaligned,
+  uint64_t xx3a : 9;
+  uint64_t old_signaller : 1;
+  uint64_t old_crawl_out : 1;
+  uint64_t xx3 : 25;
+  uint64_t dummy3 : 28;
+
+  // 2 xx4(9) bit(72) aligned,
+  uint64_t xx4[18];
+
+  // 2 v2_pl1_op_ret_base ptr, /* When a V2 PL/I program calls an operator the
+  // * operator puts a pointer to the base of
+  // * the calling procedure here. (text base ptr) */
+  struct its_pointer v2_pl1_op_ret_base;
+
+  // 2 xx5 bit(72) aligned,
+  uint64_t xx5[2];
+
+  // 2 pl1_ps_ptr ptr; /* ptr to ps for this frame; also used by fio. */
+  struct its_pointer pl1_ps_ptr;
+};
+
+#endif