Hello.

Witold Filipczyk wrote:
> And now a few programs, that don't work as they should:
> R80 - Spectrum emulator - any keypress cause exit with General 
> Protection Fault.
Yes, DPMI gets broken in 1.1.3 somehow:(
It must (and hopefully will) be fixed,
but I've no idea when:)
Try the attached patch, please
(don't forget `make clean` after
applying it).

> Pair Tetris - game from PTS-DOS - no sound, pieces don't moves down.
Do you mean it used to work with sound
under dosemu before 1.1.3?
--- src/base/dev/pic/pic.c      Tue Mar 19 19:45:50 2002
+++ src/base/dev/pic/pic.c      Tue Mar 19 19:54:14 2002
@@ -806,7 +806,7 @@
 #endif
      if(pic_ilevel < 16) pic_push(pic_ilevel);
      if (in_dpmi) {
-      run_pm_int(intr);
+      run_pm_int(intr, 1);
      } else {
 #ifndef USE_NEW_INT
       pic_cli();
--- src/dosext/dpmi/dpmi.h      Tue Mar 19 19:45:49 2002
+++ src/dosext/dpmi/dpmi.h      Tue Mar 19 19:56:56 2002
@@ -37,6 +37,7 @@
 EXTERN int in_win31 INIT(0);       /* Set to 1 when running Windows 3.1 */
 EXTERN int dpmi_eflags INIT(0);    /* used for virtual interruptflag and pending 
interrupts */
 EXTERN int in_dpmi_dos_int INIT(0);
+EXTERN int in_dpmi_hw_int INIT(0);
 EXTERN int in_dpmi_timer_int INIT(0);
 EXTERN int dpmi_mhp_TF INIT(0);
 EXTERN unsigned char dpmi_mhp_intxxtab[256] INIT({0});
@@ -47,7 +48,7 @@
 void dpmi_fault(struct sigcontext_struct *);
 #endif
 void dpmi_realmode_hlt(unsigned char *);
-void run_pm_int(int);
+void run_pm_int(int, int);
 void run_pm_mouse();
 void fake_pm_int(void);
 
--- src/dosext/dpmi/dpmi.c      Tue Mar 19 19:45:51 2002
+++ src/dosext/dpmi/dpmi.c      Tue Mar 19 21:01:00 2002
@@ -2016,8 +2016,9 @@
  * DANG_END_FUNCTION
  */
 
-void run_pm_int(int i)
+void run_pm_int(int i, int async)
 {
+  unsigned short CLIENT_PMSTACK_SEL;
   us *ssp;
 
 #ifndef USE_NEW_INT
@@ -2044,9 +2045,19 @@
     return;
   }
 
-  if (dpmi_stack_frame[current_client].ss == PMSTACK_SEL)
+  if (async && !in_dpmi_hw_int) {
+    D_printf("DPMI: Switching to locked stack\n");
+    CLIENT_PMSTACK_SEL = PMSTACK_SEL;
+  }
+  else {
+    D_printf("DPMI: Not switching to locked stack, in_dpmi_hw_int=%d\n",
+      in_dpmi_hw_int);
+    CLIENT_PMSTACK_SEL = dpmi_stack_frame[current_client].ss;
+  }
+
+  if (dpmi_stack_frame[current_client].ss == PMSTACK_SEL || in_dpmi_hw_int)
     PMSTACK_ESP = client_esp(0);
-  ssp = (us *) (GetSegmentBaseAddress(PMSTACK_SEL) +
+  ssp = (us *) (GetSegmentBaseAddress(CLIENT_PMSTACK_SEL) +
                (DPMIclient_is_32 ? PMSTACK_ESP : (PMSTACK_ESP&0xffff)));
 /* ---------------------------------------------------
        | 000FC925 | <- ssp here, executes pm int
@@ -2087,10 +2098,12 @@
   }
   dpmi_stack_frame[current_client].cs = Interrupt_Table[i].selector;
   dpmi_stack_frame[current_client].eip = Interrupt_Table[i].offset;
-  dpmi_stack_frame[current_client].ss = PMSTACK_SEL;
+  dpmi_stack_frame[current_client].ss = CLIENT_PMSTACK_SEL;
   dpmi_stack_frame[current_client].esp = PMSTACK_ESP;
   if (i == 0x08 || in_dpmi_timer_int) in_dpmi_timer_int++;
   in_dpmi_dos_int = 0;
+  if (async || in_dpmi_hw_int)
+    in_dpmi_hw_int++;
 #ifdef USE_NEW_INT
   dpmi_cli();
 #endif /* USE_NEW_INT */
@@ -2200,7 +2213,7 @@
                  case 0x1c:    /* ROM BIOS timer tick interrupt */
                  case 0x23:    /* DOS Ctrl+C interrupt */
                  case 0x24:    /* DOS critical error interrupt */
-                       run_pm_int(VM86_ARG(retval));
+                       run_pm_int(VM86_ARG(retval), 0);
                        break;
                  default:
 #ifdef USE_MHPDBG
@@ -2506,6 +2519,7 @@
   in_dpmi++;
   in_win31 = 0;
   in_dpmi_dos_int = 0;
+  in_dpmi_hw_int = 0;
   pm_block_root[current_client] = 0;
   memset((void *)(&realModeCallBack[current_client][0]), 0,
         sizeof(RealModeCallBack)*0x10);
@@ -2983,6 +2997,13 @@
 
         } else if (_eip==DPMI_OFF+1+HLT_OFF(DPMI_return_from_pm)) {
           D_printf("DPMI: Return from protected mode interrupt handler\n");
+         if (in_dpmi_hw_int) {
+           in_dpmi_hw_int--;
+           if (!in_dpmi_hw_int && _ss != PMSTACK_SEL) {
+             error("DPMI: Client's PM Stack corrupted!\n");
+             leavedos(91);
+           }
+         }
 /* ---------------------------------------------------
        |(000FC925)|
        |(dpmi_sel)|

Reply via email to