diff -Nur plex86/kernel/emulation.c plex86-jens/kernel/emulation.c
--- plex86/kernel/emulation.c	Sun Mar 26 18:52:47 2000
+++ plex86-jens/kernel/emulation.c	Fri Apr  7 09:03:51 2000
@@ -54,6 +54,7 @@
 int emulate_load_ss(vm_t *, guest_context_t *context, Bit16u selector);
 int emulate_int(vm_t *, guest_context_t *context, int vector, Bit32u eip);
 int emulate_iret(vm_t *, guest_context_t *context);
+int emulate_ljmp(vm_t *, guest_context_t *context);
 
 
 /*
@@ -644,6 +645,11 @@
         action = emulate_out(vm, context, operand_size, c);
         break;
 
+    case 0xea: /* ljmp */
+        action = emulate_ljmp(vm, context);
+        break;
+
+
     case 0xec: /* in al,dx */
         action = emulate_in(vm, context, 8, context->edx & 0xffff);
         break;
@@ -839,10 +845,22 @@
     descriptor_t *monitor_gdt;
     Bit16u limit = read_guest_word(vm, &addr);
     Bit32u base  = read_guest_dword(vm, &addr);
-
+    descriptor_t current_cs, current_ds, current_ss;
+    int nr_currents = 0;
+    Bit16u cs = context->cs;
+    Bit16u ds = context->ds;
+    Bit16u ss = context->ss;
     int i, nr_descriptors;
 
     monitor_gdt = vm->common.addr->gdt;
+
+    /* save current cs descriptor */
+    current_cs = monitor_gdt[cs >> 3];
+    current_ds = monitor_gdt[ds >> 3];
+    current_ss = monitor_gdt[ss >> 3];
+
+
+    /* "install" new gdt */
     vm->common.addr->nexus->guest_gdt_info.limit = limit;
     vm->common.addr->nexus->guest_gdt_info.base  = base;
 
@@ -892,7 +910,41 @@
     for ( ; i < MON_GDT_PAGES*PAGESIZE / 8; i++ )
         clear_descriptor(vm, monitor_gdt + i);
 
+    for (i = 1, nr_currents = 0 ; i < MON_GDT_PAGES*PAGESIZE / 8; i++ )
+      {
+        descriptor_t descr;
+
+        descr = monitor_gdt[i];
+
+	if( (nr_currents < 3) && (((Bit32u *)&descr)[0] == 0) && (((Bit32u *)&descr)[1] == 0))
+	  {
+	    /* this gdt entry is unused, we may fill it with old descriptors still needed */
+	    if(nr_currents == 0)
+	      { 
+		monitor_gdt[i] = current_cs;
+		context->cs = (i << 3) + 3;
+	      }
+	    if(nr_currents == 1)
+	      { 
+		monitor_gdt[i] = current_ds;
+		context->ds = (i << 3) + 3;
+		context->es = (i << 3) + 3;
+		context->fs = (i << 3) + 3;
+		context->gs = (i << 3) + 3;
+	      }
+	    if(nr_currents == 2)
+	      { 
+		monitor_gdt[i] = current_ss;
+		context->ss = (i << 3) + 3;
+	      }
+	    nr_currents++;
+	  } 
+
+      }
+
+
     /* Mark current CS active */
+    codeseg_activate(vm, cs, 0);
     codeseg_activate(vm, context->cs, 1);
 
     /* We have just clobbered the monitor selectors.  Zero them out in the
@@ -977,11 +1029,20 @@
       * Emulate instruction that loads DS register
       */
 {
-    vm->common.addr->nexus->debug_msg.msg_code = EMU_LOAD_SEGREG_MSG;
-    vm->common.addr->nexus->debug_msg.para1 = 'D';
-    vm->common.addr->nexus->debug_msg.para2 = selector;
-
-    return 0;
+  descriptor_t *monitor_gdt;
+ 
+  monitor_gdt = vm->common.addr->gdt;
+
+  // force the segment to 3;
+  // this should also be done in lgdt emulation, if so, loading ds would not;
+  // trap - but it traps, so dpl is not 3...
+  monitor_gdt[selector >> 3].dpl = D_DPL3;
+
+  // selectors RPL is not used (useless?), because epl is max(cpl, rpl);
+  // and cpl is 3, so always epl is 3...
+  //context->ds = selector | 3;
+  context->ds = selector;
+  return 2;
 }
 
 int
@@ -1268,4 +1329,38 @@
 {
     context->event_info = EMU_INSTR_HLT | (RET_BECAUSE_USEREMU << 8);
     return 4;
+}
+
+
+int
+emulate_ljmp(vm_t *vm, guest_context_t *context)
+     /* ljmp may be an intersegment call
+      * we have disabled intersegment calls, so we have to emulate them
+      */
+{
+  descriptor_t *monitor_gdt;
+  Bit16u new_cs;
+  Bit32u new_eip;
+  Bit32u eip = context->eip + 1;
+
+  monitor_gdt = vm->common.addr->gdt;
+
+  new_eip = read_guest_dword(vm, &eip);
+  new_cs = read_guest_word(vm, &eip);
+
+  /* now we have new cs:eip, lets prepare new code segment descriptor (DPL, CODE) */
+  monitor_gdt[new_cs >> 3].dpl = D_DPL3;
+  monitor_gdt[new_cs >> 3].type = D_CODE;
+
+  context->cs = new_cs | 3;
+  context->eip = new_eip;
+
+#if 1
+  return 1;
+
+#else
+  context->event_info = EMU_INSTR_HLT | (RET_BECAUSE_USEREMU << 8);
+  context->error = context->ds;
+  return 0;
+#endif
 }
