Implement self-links and *system links
authorNick Downing <nick@ndcode.org>
Thu, 24 Oct 2019 12:06:12 +0000 (23:06 +1100)
committerNick Downing <nick@ndcode.org>
Thu, 24 Oct 2019 12:06:12 +0000 (23:06 +1100)
definition_dcls.h
dps8/dps8_addrmods.c
dps8/dps8_cpu.c
dps8/dps8_faults.c
dps8/dps8_ins.c
multics_sim.c

index 22c0e50..e5edad9 100644 (file)
@@ -306,10 +306,10 @@ struct link_init {
 // declare 1 link_init_copy_info aligned based (link_init_ptr),
 struct link_init_copy_info {
   // 2 header aligned like link_init,
-  int64_t n_words : 36;
+  int64_t header_n_words : 36;
   uint64_t dummy0 : 28;
   uint64_t dummy1 : 18;
-  uint64_t type : 18;
+  uint64_t header_type : 18;
   uint64_t dummy2 : 28;
 
   // 2 initial_data (link_init_n_words refer (link_init_copy_info.header.n_words)) bit (36) aligned;
@@ -353,11 +353,11 @@ struct list_template_entry {
 struct link_init_list_template {
   // 2 header aligned like link_init,
   // 2 pad bit (18) unaligned,
-  int64_t n_words : 36;
+  int64_t header_n_words : 36;
   uint64_t dummy0 : 28;
-  uint64_t pad_bit : 18;
+  uint64_t header_pad_bit : 18;
   uint64_t type : 18;
-  uint64_t dummy1 : 28;
+  uint64_t header_dummy1 : 28;
 
   // 2 n_words_in_list fixed bin (18) unsigned unaligned,
   uint64_t dummy2 : 18;
@@ -413,8 +413,9 @@ struct link_init_deferred_aligned {
   uint64_t dummy1 : 28;
 
   // 2 link_relp fixed bin (18) unsigned unaligned;
+  uint64_t dummy2 : 18;
   uint64_t link_relp : 18;
-  uint64_t dummy2 : 46;
+  uint64_t dummy3 : 28;
 };
 
 /* Definition section hash table */
index 3846e86..8bae7b7 100644 (file)
@@ -577,9 +577,6 @@ 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 3f13401..784ebe3 100644 (file)
@@ -3166,7 +3166,8 @@ int32 core_read (/*word24*/word36 addr, word36 *data, const char * ctx)
       }
 #else
 #ifndef LOCKLESS
- //printf("addr %012llo\n", addr);
+ //fprintf(stderr, "addr %012llo\n", addr);
+ fprintf(stderr, "addr %012llo word %012llo\n", addr, M[(addr >> 18) & 077777][addr & 0777777]);
     if (M[(addr >> 18) & 077777][addr & 0777777] & MEM_UNINITIALIZED)
       {
         sim_debug (DBG_WARN, & cpu_dev,
index e186fb5..271c802 100644 (file)
@@ -356,6 +356,12 @@ const _fault_subtype fst_onc_nem = (_fault_subtype) {.fault_onc_subtype=flt_onc_
 void doFault (_fault faultNumber, _fault_subtype subFault, 
               const char * faultMsg)
   {
+ void snap_link(void);
+ if (faultNumber == FAULT_F2) {
+  snap_link();
+  cpu.cycle = FETCH_cycle;
+  longjmp (cpu.jmpMain, JMP_REENTRY);
+ }
 #ifdef LOOPTRC
 if (faultNumber == FAULT_TRO)
 {
index 3ef542b..afd1516 100644 (file)
@@ -6653,10 +6653,10 @@ static t_stat doInstruction (void)
 
         /// MISCELLANEOUS INSTRUCTIONS
 
-//        case x0 (0633):  // rccl
-//          // 00...0 -> C(AQ)0,19
-//          // C(calendar clock) -> C(AQ)20,71
-//          {
+        case x0 (0633):  // rccl
+          // 00...0 -> C(AQ)0,19
+          // C(calendar clock) -> C(AQ)20,71
+          {
 //// XXX see ticket #23
 //            // For the rccl instruction, the first 2 or 3 bits of the addr
 //            // field of the instruction are used to specify which SCU.
@@ -6682,42 +6682,42 @@ static t_stat doInstruction (void)
 //            HDBGRegQ ();
 //            if (rc > 0)
 //              return rc;
-//#ifndef SPEED
-//            if_sim_debug (DBG_TRACEEXT, & cpu_dev)
-//              {
-//                // Clock at initialization
-//                // date -d "Tue Jul 22 16:39:38 PDT 1999" +%s
-//                // 932686778
-//                uint64 UnixSecs = 932686778;
-//                uint64 UnixuSecs = UnixSecs * 1000000LL;
-//                // now determine uSecs since Jan 1, 1901 ...
-//                uint64 MulticsuSecs = 2177452800000000LL + UnixuSecs;
-//
-//                // Back into 72 bits
-//               word72 big = convert_to_word72 (cpu.rA, cpu.rQ);
-//#ifdef NEED_128
-//                // Convert to time since boot
-//                big = subtract_128 (big, construct_128 (0, MulticsuSecs));
-//                uint32_t remainder;
-//                uint128 bigsecs = divide_128_32 (big, 1000000u, & remainder);
-//                uint64_t uSecs = remainder;
-//                uint64_t secs = bigsecs.l;
-//                sim_debug (DBG_TRACEEXT, & cpu_dev,
-//                           "Clock time since boot %4llu.%06llu seconds\n",
-//                           secs, uSecs);
-//#else
-//                // Convert to time since boot
-//                big -= MulticsuSecs;
-//                unsigned long uSecs = big % 1000000u;
-//                unsigned long secs = (unsigned long) (big / 1000000u);
-//                sim_debug (DBG_TRACEEXT, & cpu_dev,
-//                           "Clock time since boot %4lu.%06lu seconds\n",
-//                           secs, uSecs);
-//#endif
-//              }
-//#endif
-//          }
-//          break;
+#ifndef SPEED
+            if_sim_debug (DBG_TRACEEXT, & cpu_dev)
+              {
+                // Clock at initialization
+                // date -d "Tue Jul 22 16:39:38 PDT 1999" +%s
+                // 932686778
+                uint64 UnixSecs = 932686778;
+                uint64 UnixuSecs = UnixSecs * 1000000LL;
+                // now determine uSecs since Jan 1, 1901 ...
+                uint64 MulticsuSecs = 2177452800000000LL + UnixuSecs;
+
+                // Back into 72 bits
+               word72 big = convert_to_word72 (cpu.rA, cpu.rQ);
+#ifdef NEED_128
+                // Convert to time since boot
+                big = subtract_128 (big, construct_128 (0, MulticsuSecs));
+                uint32_t remainder;
+                uint128 bigsecs = divide_128_32 (big, 1000000u, & remainder);
+                uint64_t uSecs = remainder;
+                uint64_t secs = bigsecs.l;
+                sim_debug (DBG_TRACEEXT, & cpu_dev,
+                           "Clock time since boot %4llu.%06llu seconds\n",
+                           secs, uSecs);
+#else
+                // Convert to time since boot
+                big -= MulticsuSecs;
+                unsigned long uSecs = big % 1000000u;
+                unsigned long secs = (unsigned long) (big / 1000000u);
+                sim_debug (DBG_TRACEEXT, & cpu_dev,
+                           "Clock time since boot %4lu.%06lu seconds\n",
+                           secs, uSecs);
+#endif
+              }
+#endif
+          }
+          break;
 
         case x0 (0002):   // drl
           // Causes a fault which fetches and executes, in absolute mode, the
index 84d0b20..ba1f915 100644 (file)
@@ -57,6 +57,15 @@ char *paths[N_PATHS] = {
   "tape/word/system_library_unbundled/"
 };
 
+#define N_SYSTEM_LINK 0x100
+int n_system_link;
+struct system_link {
+  struct system_link *next;
+  int n_words;
+  int offset;
+  char name[NAME_LEN];
+} system_link[N_SYSTEM_LINK];
+
 #define N_LOADED_SEGMENT 0x100
 int n_loaded_segment;
 struct loaded_segment {
@@ -64,6 +73,7 @@ struct loaded_segment {
   int segment;
   int bitcount;
   int linkage_offset;
+  struct system_link *system_link_head;
 } loaded_segment[N_LOADED_SEGMENT];
 
 #define N_SEGMENT 0x200
@@ -160,7 +170,7 @@ const char *xlate_segment(const char *name) {
           char *r = strchr(q, '\n');
           if (r)
             *r = 0;
-          printf("xlate segname %s to %s\n", name, q);
+          fprintf(stderr, "xlate segname %s to %s\n", name, q);
           return q;
         }
       }
@@ -168,7 +178,7 @@ const char *xlate_segment(const char *name) {
     fclose(fp);
   }
 
-  printf("can't xlate segname %s\n", name);
+  fprintf(stderr, "can't xlate segname %s\n", name);
   return name;
 }
 
@@ -186,7 +196,7 @@ struct loaded_segment *load_segment(const char *name) {
   rassert(p->name);
 
   p->segment = allocate_segment();
-  printf("load segname %s into segment %06o\n", name, p->segment);
+  fprintf(stderr, "load segname %s into segment %06o\n", name, p->segment);
   loaded_segment_xref[p->segment] = p;
 
   // search for segment in path
@@ -202,8 +212,8 @@ struct loaded_segment *load_segment(const char *name) {
       M[p->segment] = (word36 *)mmap(
         NULL,
         01000000 * sizeof(uint64_t),
-        PROT_READ,
-        MAP_SHARED,
+        PROT_READ | PROT_WRITE,
+        MAP_PRIVATE,
         fd,
         (off_t)0
       );
@@ -247,20 +257,41 @@ found_segment:
 
 found_bitcount:
   ;
+  // validate linkage header
   struct object_map *object_map = get_object_map(p);
   rassert(
     object_map->linkage_length >=
       sizeof(struct linkage_header) / sizeof(uint64_t)
   );
+  struct virgin_linkage_header *virgin_linkage_header =
+    (struct virgin_linkage_header *)(
+      M[p->segment] + object_map->linkage_offset
+    );
+  rassert(virgin_linkage_header->def_offset == object_map->definition_offset);
+  rassert(virgin_linkage_header->first_ref_relp == 0);
+  rassert(virgin_linkage_header->static_length == object_map->static_length);
 
   // copy and fill in linkage section
   p->linkage_offset = allocate_linkage(object_map->linkage_length, 2);
+  fprintf(
+    stderr,
+    "allocate_linkage %06o$[%06o, %06o)\n",
+    linkage_segment,
+    p->linkage_offset,
+    p->linkage_offset + (int)object_map->linkage_length
+  );
+  if (strcmp(p->name, "hcs_") == 0)
+    // patch in .my_lp
+    *(struct its_pointer *)(M[p->segment] + 0312) = its_pointer(
+      linkage_segment,
+      p->linkage_offset
+    );
   struct linkage_header *linkage_header = (struct linkage_header *)(
     M[linkage_segment] + p->linkage_offset
   );
   memcpy(
     linkage_header,
-    M[p->segment] + object_map->linkage_offset,
+    virgin_linkage_header,
     object_map->linkage_length * sizeof(uint64_t)
   );
   linkage_header->def_ptr = its_pointer(
@@ -290,6 +321,7 @@ found_bitcount:
   isot[p->segment] = packed_pointer(linkage_segment, static_offset);
   stack_header->cur_lot_size = next_segment;
 
+  p->system_link_head = NULL;
   return p;
 }
 
@@ -303,10 +335,10 @@ void get_acc_string(uint64_t *acc_string, char *buf, int buf_len) {
   buf[len] = 0;
 }
 
-int find_entry(
+struct its_pointer find_definition(
   struct loaded_segment *p,
-  const char *entry_segname,
-  const char *entry_name,
+  const char *name,
+  int class,
   bool entry
 ) {
   struct object_map *object_map = get_object_map(p);
@@ -323,55 +355,58 @@ int find_entry(
       (uint64_t *)definition_header + definition->forward_relp
     )
   ) {
+    rassert(definition->class <= CLASS_HEAP);
     if (
-      definition->class == CLASS_TEXT &&
+      definition->class != CLASS_SEGNAME &&
       !definition->flags_ignore &&
+      (class == -1 || definition->class == class) &&
       (!entry || definition->flags_entry)
     ) {
-#if 0 // arg_list_ptr_$arg_list_ptr_ should be wired_utility_$arg_list_ptr_
-      struct segname_definition *segname_definition =
-        (struct segname_definition *)(
-          (uint64_t *)definition_header + definition->segname_relp
-        );
-      rassert(segname_definition->class == CLASS_SEGNAME);
-
-      char segname[NAME_LEN];
+      char definition_name[NAME_LEN];
       get_acc_string(
-        (uint64_t *)definition_header + segname_definition->name_relp,
-        segname,
-        sizeof(segname)
+        (uint64_t *)definition_header + definition->name_relp,
+        definition_name,
+        sizeof(definition_name)
       );
 
-      if (strcmp(segname, entry_segname) == 0) {
-#endif
-        char name[NAME_LEN];
-        get_acc_string(
-          (uint64_t *)definition_header + definition->name_relp,
-          name,
-          sizeof(name)
-        );
-
-        if (strcmp(name, entry_name) == 0)
-          return (int)(object_map->text_offset + definition->thing_relp);
-#if 0
-      }
-#endif
+      if (strcmp(definition_name, name) == 0)
+        switch (definition->class) {
+        case CLASS_TEXT:
+          return its_pointer(
+            p->segment,
+            (int)(object_map->text_offset + definition->thing_relp)
+          );
+        case CLASS_LINKAGE:
+          return its_pointer(
+            linkage_segment,
+            (int)(p->linkage_offset + definition->thing_relp)
+          );
+        default:
+          fprintf(
+            stderr,
+            "unimplemented class %s in definition %s$%s\n",
+            class_names[definition->class],
+            p->name,
+            name
+          );
+          exit(EXIT_FAILURE);
+        }
     }
   }
 
   fprintf(
     stderr,
-    "can't find entry %s$%s in segment %s\n",
-    entry_segname,
-    entry_name,
-    p->name
+    "can't find definition %s$%s\n",
+    p->name,
+    name
   );
   exit(EXIT_FAILURE);
 }
 
 // callback from simulator when fault type 2 occurs
-bool snap_link(void) {
-  printf(
+void snap_link(void) {
+  fprintf(
+    stderr,
     "fault type 2 at %06o:%06o accessing %06o:%06o\n",
     cpu.PPR.PSR,
     cpu.PPR.IC,
@@ -380,11 +415,9 @@ bool snap_link(void) {
   );
 
   // find segment of faulting instruction (for validation purposes)
-  if (cpu.PPR.PSR >= N_SEGMENT)
-    return false;
+  rassert(cpu.PPR.PSR < N_SEGMENT);
   struct loaded_segment *p = loaded_segment_xref[cpu.PPR.PSR];
-  if (p == NULL)
-    return false;
+  rassert(p);
 
   // validate link address, using read-only linkage section (safer)
   struct object_map *object_map = get_object_map(p);
@@ -392,15 +425,14 @@ bool snap_link(void) {
     (struct virgin_linkage_header *)(
       M[p->segment] + object_map->linkage_offset
     );
-  if (
-     cpu.TPR.TSR != linkage_segment ||
-     cpu.TPR.CA & 1 ||
-     cpu.TPR.CA <
-       p->linkage_offset + virgin_linkage_header->first_ref_relp ||
-     cpu.TPR.CA >=
-       p->linkage_offset + object_map->linkage_length
-   )
-     return false;
+  rassert(
+    cpu.TPR.TSR == linkage_segment &&
+    (cpu.TPR.CA & 1) == 0 &&
+    cpu.TPR.CA >=
+      p->linkage_offset + virgin_linkage_header->first_ref_relp &&
+    cpu.TPR.CA <
+      p->linkage_offset + object_map->linkage_length
+  );
 
   // validate link, using read-only linkage section (safer)
   int link_relp = (int)(cpu.TPR.CA - p->linkage_offset);
@@ -414,8 +446,7 @@ bool snap_link(void) {
   struct its_pointer *link = (struct its_pointer *)(
     M[cpu.TPR.TSR] + cpu.TPR.CA
   );
-  if (memcmp(link, virgin_link, sizeof(struct link)))
-    return false;
+  rassert(memcmp(link, virgin_link, sizeof(struct link)) == 0);
 
   // look up link target
   struct definition_header *definition_header = (struct definition_header *)(
@@ -427,53 +458,109 @@ bool snap_link(void) {
   struct type_pair *type_pair = (struct type_pair *)(
     (uint64_t *)definition_header + exp_word->type_relp
   );
+  //rassert(type_pair->trap_relp == 0);
   rassert(
     type_pair->type >= LINK_SELF_BASE &&
       type_pair->type <= LINK_CREATE_IF_NOT_FOUND
   );
 
   // process link by type
+  char offsetname[NAME_LEN];
+  get_acc_string(
+    (uint64_t *)definition_header + type_pair->offsetname_relp,
+    offsetname,
+    sizeof(offsetname)
+  );
+
+  char segname[NAME_LEN];
+  static const int section_to_class[] = {
+    CLASS_TEXT,
+    CLASS_LINKAGE,
+    CLASS_SYMBOL,
+    -1,
+    CLASS_STATIC
+  };
   switch (type_pair->type) {
   case LINK_REFNAME_OFFSETNAME:
-    {
-      char segname[NAME_LEN];
-      get_acc_string(
-        (uint64_t *)definition_header + type_pair->segname_relp,
-        segname,
-        sizeof(segname)
-      );
-
-      char offsetname[NAME_LEN];
-      get_acc_string(
-        (uint64_t *)definition_header + type_pair->offsetname_relp,
+    rassert(type_pair->trap_relp == 0);
+    get_acc_string(
+      (uint64_t *)definition_header + type_pair->segname_relp,
+      segname,
+      sizeof(segname)
+    );
+    *link = find_definition(
+      load_segment(xlate_segment(segname)),
+      offsetname,
+      -1,
+      false
+    );
+    break;
+  case LINK_SELF_OFFSETNAME:
+    switch (type_pair->segname_relp) {
+    case SECTION_TEXT: // 0
+    case SECTION_LINK: // 1
+    case SECTION_SYMBOL: // 2
+    case SECTION_STATIC: // 4
+      rassert(type_pair->trap_relp == 0);
+      *link = find_definition(
+        p,
         offsetname,
-        sizeof(offsetname)
+        section_to_class[type_pair->segname_relp],
+        false
       );
-
-      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;
+    case SECTION_SYSTEM:
+      ;
+      struct link_init *link_init = (struct link_init *)(
+        (uint64_t *)definition_header + type_pair->trap_relp
       );
+      rassert(link_init->n_words < 01000000);
+      rassert(link_init->type == INIT_NO_INIT);
+
+      {
+        struct system_link *q;
+        for (q = p->system_link_head; q; q = q->next)
+          if (strcmp(q->name, offsetname) == 0) {
+            rassert(q->n_words == (int)link_init->n_words);
+            goto found_system_link;
+          }
+
+        rassert(n_system_link < N_SYSTEM_LINK);
+        q = system_link + n_system_link++;
+        q->n_words = (int)link_init->n_words;
+        q->offset = allocate_linkage((int)link_init->n_words, 2);
+        strcpy(q->name, offsetname);
+
+      found_system_link:
+        *link = its_pointer(linkage_segment, q->offset);
+      }
+      break;
     }
     break;
   default:
-    rassert(false);
+    fprintf(
+      stderr,
+      "unimplemented link type %s\n",
+      link_type_names[type_pair->type - 1]
+    );
+    exit(EXIT_FAILURE);
   }
 
-  return true;
+  link->address += exp_word->expression;
+  link->modifier1 = virgin_link->modifier;
+  fprintf(
+    stderr,
+    "snap link %06o:%06o -> %s$%s + %06o -> %06o:%06o\n",
+    (int)cpu.TPR.TSR,
+    (int)cpu.TPR.CA,
+    type_pair->type == LINK_SELF_OFFSETNAME ?
+      symbolic_section_names[type_pair->segname_relp] :
+      segname,
+    offsetname,
+    (int)exp_word->expression,
+    (int)link->segment,
+    (int)link->address
+  );
 }
 
 int main(int argc, char **argv) {
@@ -504,7 +591,7 @@ int main(int argc, char **argv) {
   // initialize CPU
   sim_deb = stderr;
   cpu_dev.dctrl =
-    //DBG_TRACE |
+    DBG_TRACE |
     //DBG_MSG |
     //DBG_REGDUMPAQI |
     //DBG_REGDUMPIDX |
@@ -513,7 +600,6 @@ int main(int argc, char **argv) {
     //DBG_REGDUMPDSBR |
     //DBG_REGDUMPFLT |
     //DBG_REGDUMP |
-    //DBG_REGDUMP |
     //DBG_ADDRMOD |
     //DBG_APPENDING |
     //DBG_TRACEEXT |
@@ -571,35 +657,42 @@ int main(int argc, char **argv) {
 
   // load pl1 operators
   struct loaded_segment *p = load_segment(xlate_segment("pl1_operators_"));
-  int operator_table_offset = find_entry(
+  struct its_pointer operator_table_pointer = find_definition(
     p,
-    "pl1_operators_",
     "operator_table",
+    -1,
     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->pl1_operators_ptr = operator_table_pointer;
+  stack_header->call_op_ptr = find_definition(
+    p,
+    "alm_call",
+    -1,
+    false
   );
-  stack_header->push_op_ptr = its_pointer(
-    p->segment,
-    find_entry(p, "pl1_operators_", "alm_push", false)
+  stack_header->push_op_ptr = find_definition(
+    p,
+    "alm_push",
+    -1,
+    false
   );
-  stack_header->return_op_ptr = its_pointer(
-    p->segment,
-    find_entry(p, "pl1_operators_", "alm_return", false)
+  stack_header->return_op_ptr = find_definition(
+    p,
+    "alm_return",
+    -1,
+    false
   );
-  stack_header->no_pop_op_ptr = its_pointer(
-    p->segment,
-    find_entry(p, "pl1_operators_", "alm_return_no_pop", false)
+  stack_header->no_pop_op_ptr = find_definition(
+    p,
+    "alm_return_no_pop",
+    -1,
+    false
   );
-  stack_header->entry_op_ptr = its_pointer(
-    p->segment,
-    find_entry(p, "pl1_operators_", "alm_entry", false)
+  stack_header->entry_op_ptr = find_definition(
+    p,
+    "alm_entry",
+    -1,
+    false
   );
 
   // create first stack frame
@@ -687,17 +780,22 @@ int main(int argc, char **argv) {
   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.rA = (word36)(n_args_af) << 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;
+  cpu.PR[0].SNR = operator_table_pointer.segment;
+  cpu.PR[0].WORDNO = operator_table_pointer.address;
 
-  struct loaded_segment *q = load_segment(xlate_segment(entry_segname));
+  struct its_pointer entry_pointer = find_definition(
+    load_segment(xlate_segment(entry_segname)),
+    entry_name,
+    -1,
+    true
+  );
   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[2].SNR = entry_pointer.segment;
+  cpu.PR[2].WORDNO = entry_pointer.address;
 
   cpu.PR[6].RNR = 3;
   cpu.PR[6].SNR = stack_segment;