Release 950727

Sat Jul 22 22:39:09 IDT 1995 Michael Veksler <e1678223@tochnapc2.technion.ac.il>

	* [ipc/*]
	New directory. This directory contains the new inter-wine
 	communications support. It enables DDE protocols between two wine
 	instances.  Currently it is limited to DDE, but can be enhanced to
 	support OLE between 2 different wine instances.  This is very
 	important for libwine.a DDE/OLE support.

	* [tools/ipcl]
    	A script to delete garbage IPC handles (shared memory, semaphores
 	and message queues).  The current inter-wine communication is not
 	perfect, and sometimes leaves garbage behind.

	* [if1632/relay.c] [include/atom.h] [include/global.h]
 	[loader/selector.c] [loader/task.c] [loader/module.c]
 	[loader/signal.c] [memory/global.c] [misc/atom.c]
 	[windows/class.c] [windows/message.c] [windows/win.c]
	[Imakefile]
    	Hooks for inter-wine DDE support, current Global.*Atom functions
 	renamed to Local.*Atom since Global.*Atom are used for Inter-Wine
 	DDE communication. (The first call to these functions sets up the
 	IPC structures - which otherwise cause unneeded overhead.

Mon Jul 17 19:55:21 1995  Alexandre Julliard  <julliard@sunsite.unc.edu>

	* [controls/menu.c]
	Don't crash if a NULL string is passed to menu functions.

	* [memory/selector.c]
	We now use a bit in ldt_flags_copy to indicate free LDT entries.
	Fixed a bug in SELECTOR_ReallocBlock that could cause it to
	overwrite valid LDT entries when growing a block.

	* [miscemu/instr.c]
	Emulate int xx instruction by storing the interrupt vector in
	CS:IP and returning directly. This allows a program to install an
	interrupt vector.

	* [windows/win.c]
	Added function WIN_GetTopParent to get the top-level parent of a
	window.

Sun Jul  16 18:17:17 1995  Gregory Trubetskoy <grisha@mira.com>

        * [loader/resource.c]
        Added LoadIconHandler. It doesn't do anything yet, but now you
        can use borland help files with winhelp.exe.

Sun Jul 16 11:58:45 1995 Anand Kumria <akumria@ozemail.com.au>

	* [misc/main.c]
	Fixed to return 386 Enhanced mode correctly. Also return the same
 	type of CPU, for both Enhanced and Standard mode, namely a 386.

Sun Jul 16 00:02:04 1995    Martin von Loewis <loewis@informatik.hu-berlin.de>

	* [Configure] [include/options.h] [include/wineopts.h]
	  [misc/main.c][misc/spy.c]
	  Removed support of spy file. Redirected spy messages to stddeb.
	  Removed -spy option. Added -debugmsg +spy option.

	* [debugger/dbg.y][debugger/debug.l]
	Enabled segmented addresses (seg:offs) for break and x commands.

	* [if1632/gdi.spec] [objects/region.c] [windows/graphics.c]
	  [include/region.h]
	FrameRgn, REGION_FrameRgn: New functions

	* [if1632/kernel.spec]
	IsWinOldApTask: Return false

	* [if1632/mouse.spec]
	CplApplet: Removed

	* [if1632/user.spec] [windows/win.c]
	ShowOwnedPopups: New function

	* [if1632/winsock.spec] [misc/winsocket.c]
	inet_addr, select: New prototypes in relay code
	Fixed memory layout for netdb functions (getXbyY).
	WINSOCK_ioctlsocket: Translated FIONREAD, FIONBIO, and FIOASYNC

	* [objects/clipping.c]
	RectVisible: Fixed call to LPToDP

	* [rc/winerc.c]
	main: Removed extra argument to getopt for Linux.

Tue Jul 11 00:14:41 1995   Bernd Schmidt <crux@pool.informatik.rwth-aachen.de>

        * [controls/listbox.c]
	Yet another fix for ListBoxDirectory().
	
	* [loader/module.c] [if1632/kernel.spec]
	Make GetModuleHandle() accept instance handles as parameter.

        * [if1632/relay.c] [loader/task.c]
	Put a magic cookie at the bottom of the 32 bit stack, and check on
	each return from a 32 bit function whether it's still there. Complain
	if it's not.

        * [if1632/user.spec]
	Wrong entry for CloseDriver().

	* [misc/dos_fs.c] [loader/task.c] [include/dos_fs.h] [misc/file.c]
	[miscemu/int21.c]
	Large parts of dos_fs.c simplified. Changed it to use one
	current drive/directory per task, which is set to the module path on
	task creation.
	Prevent CorelPaint from closing stdin.
	open() with O_CREAT set must be passed three parameters.
	DOS FindFirst()/FindNext() could crash when FA_LABEL was set. Fixed,
	it's in DOS_readdir() now.

	* [misc/profile.c]
	Some badly written software (Lotus Freelance Graphics) passes a bogus
	size parameter that caused Wine to write off the end of a segment.
	Fixed. (It's probably too paranoid now.)
	
	* [multimedia/mmsystem.c] [multimedia/time.c] [multimedia/joystick.c]
	[multimedia/Imakefile] [if1632/winprocs.spec]
	16 bit entry point for MMSysTimeCallback.
	Split off time.c and joystick.c from mmsystem.c.
	
	* [objects/dib.c]
	GetDIBits(): call XGetImage() via CallTo32_LargeStack.

        * [windows/cursor.c]
	DestroyCursor(): do nothing for builtin cursors.
	
	* [windows/mdi.c]
	Half of WM_MDISETMENU implemented.
	
	* [windows/win.c]
	EnumWindows() and EnumTaskWindows() never enumerated any windows.
	Fixed.

	* [windows/*.c]
	Fixed GetParent() to return correct values for owned windows.

	* [windows/message.c]
	Don't try to activate disabled top-level windows.

        * [windows/nonclient.c]
	Work around a bug in gcc-2.7.0.
	
	* [tools/build.c] [include/stackframe.h] [memory/global.c] 
	[loader/task.c] [memory/selector.c]
	Some Visual Basic programs (and possibly others, too) expect ES to be 
	preserved by a call to an API function, so we have to save it.
	In GlobalFree() and FreeSelector(), we must clear CURRENT_STACK16->es 
	to prevent segfaults if ES contained the selector to be freed.

Sun Jul  9 20:21:20 1995  Jon Tombs  <jon@gtex02.us.es>

	* [*/*]
	Added missing prototypes to header files and relevant includes
	to reduce compile time warnings.

Sun Jul  9 18:32:56 1995  Michael Patra  <micky@marie.physik.tu-berlin.de>

	* [configure.in] [include/config.h] [*/Makefile.in]
	New configuration scheme based on autoconf.

Sat Jul  8 14:12:45 1995  Morten Welinder  <terra+@cs.cmu.edu>

	* [miscemu/ioports.c]
	Revamp to have only one in- and one out- variant, both really
 	implemented.

	* [miscemu/instr.c]
	INSTR_EmulateInstruction: Use new ioport interface.  Implement
 	string io.  Correct instruction pointer for 32-bit code.

	* [include/miscemu.h]
	Update port function prototypes.

	* [include/registers.h]
	Defined FS and GS.

Sat Jul  8 13:38:54 1995  Hans de Graaff  <graaff@twi72.twi.tudelft.nl>

	* [misc/dos_fs.c]
	ChopOffSlash(): A path consisting off a single slash is left
 	intact, and multiple slashes are all removed.
diff --git a/miscemu/Imakefile b/miscemu/Imakefile
index a73da1c..74a89df 100644
--- a/miscemu/Imakefile
+++ b/miscemu/Imakefile
@@ -8,8 +8,6 @@
 	instr.c \
 	int10.c \
 	int13.c \
-	int15.c \
-	int16.c \
 	int1a.c \
 	int21.c \
 	int25.c \
diff --git a/miscemu/Makefile.in b/miscemu/Makefile.in
new file mode 100644
index 0000000..8cf8cce
--- /dev/null
+++ b/miscemu/Makefile.in
@@ -0,0 +1,51 @@
+CC 	= @CC@
+CFLAGS 	= @CFLAGS@
+XINCL 	= @x_includes@
+TOPSRC  = @top_srcdir@
+DIVINCL = -I$(TOPSRC)/include
+LD	= @LD@
+LDCOMBINEFLAGS = @LDCOMBINEFLAGS@
+
+
+MODULE 	= miscemu
+
+SRCS 	= dpmi.c emulate.c instr.c int10.c int13.c \
+        int1a.c int21.c int25.c int26.c int2a.c int2f.c int5c.c interrupts.c \
+        ioports.c
+
+OBJS = $(SRCS:.c=.o)
+
+.c.o:
+	$(CC) -c $(CFLAGS) $(XINCL) $(DIVINCL) -o $*.o $<
+
+all: $(MODULE).o
+
+$(MODULE).o: $(OBJS)
+	$(LD) $(LDCOMBINEFLAGS) $(OBJS) -o $(MODULE).o
+
+depend:
+	sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
+	$(CC) $(DIVINCL) $(XINCL) -MM *.c >> tmp_make
+	cp tmp_make Makefile
+	rm tmp_make
+
+clean:
+	rm -f *.o \#*\# *~ tmp_make
+
+distclean: clean
+	rm Makefile
+
+countryclean:
+
+NAMES = $(SRCS:.c=)
+
+winelibclean:
+	for i in $(NAMES); do \
+	if test `grep -c WINELIB $$i.c` -ne 0; then \
+	rm $$i.o; \
+	fi; \
+	done
+ 
+dummy:
+
+### Dependencies:
diff --git a/miscemu/dpmi.c b/miscemu/dpmi.c
index c44a6af..2b63159 100644
--- a/miscemu/dpmi.c
+++ b/miscemu/dpmi.c
@@ -18,19 +18,16 @@
 
 
 /**********************************************************************
- *	    do_int31
+ *	    INT_Int31Handler
  *
- * Handle the DPMI interrupt (int 31h).
+ * Handler for int 31h (DPMI).
  */
-int do_int31( struct sigcontext_struct *context )
+void INT_Int31Handler( struct sigcontext_struct sigcontext )
 {
+#define context (&sigcontext)
     DWORD dw;
     BYTE *ptr;
 
-    dprintf_int( stddeb, "int31 (DPMI): AX %04x, BX %04x, CX %04x, DX %04x, "
-                 "SI %04x, DI %04x, DS %04x, ES %04x\n",
-                 AX, BX, CX, DX, SI, DI, DS, ES );
-
     ResetCflag;
     switch(AX)
     {
@@ -116,16 +113,27 @@
         SetCflag;
         break;
 
+    case 0x0204:  /* Get protected mode interrupt vector */
+	dw = (DWORD)INT_GetHandler( BL );
+	CX = HIWORD(dw);
+	DX = LOWORD(dw);
+	break;
+
+    case 0x0205:  /* Set protected mode interrupt vector */
+	INT_SetHandler( BL, (SEGPTR)MAKELONG( DX, CX ) );
+	break;
+
     case 0x0400:  /* Get DPMI version */
-        AX = 0x0009;  /* DPMI version 0.9 */
+        AX = 0x005a;  /* DPMI version 0.90 */
         BX = 0x0005;  /* Flags: 32-bit, virtual memory */
-        CL = 4;       /* CPU type: 486 */
+        CL = 3;       /* CPU type: 386 */
         DX = 0x0102;  /* Master and slave interrupt controller base */
         break;
 
     case 0x0500:  /* Get free memory information */
-        memset( PTR_SEG_OFF_TO_LIN( ES, DI ),
-                0xff, 0x30 );  /* No information supported */
+        ptr = (BYTE *)PTR_SEG_OFF_TO_LIN( ES, DI );
+        *(DWORD *)ptr = 0x00ff0000; /* Largest block available */
+        memset( ptr + 4, 0xff, 0x2c );  /* No other information supported */
         break;
 
     case 0x0501:  /* Allocate memory block */
@@ -165,9 +173,10 @@
         break;  /* Just ignore it */
 
     default:
+        INT_BARF( 0x31 );
         AX = 0x8001;  /* unsupported function */
         SetCflag;
         break;
     }
-    return 1;
+#undef context
 }
diff --git a/miscemu/instr.c b/miscemu/instr.c
index b025452..3be1990 100644
--- a/miscemu/instr.c
+++ b/miscemu/instr.c
@@ -6,55 +6,11 @@
 
 #include <stdio.h>
 #include "windows.h"
-#include "dos_fs.h"
 #include "ldt.h"
 #include "miscemu.h"
 #include "registers.h"
 
 
-static int do_int(int intnum, struct sigcontext_struct *context)
-{
-	switch(intnum)
-	{
-	      case 0x10: return do_int10(context);
-
-	      case 0x11:  
-		AX = DOS_GetEquipment();
-		return 1;
-
-	      case 0x12:               
-		AX = 640;
-		return 1;	/* get base mem size */                
-
-              case 0x13: return do_int13(context);
-	      case 0x15: return do_int15(context);
-	      case 0x16: return do_int16(context);
-	      case 0x1a: return do_int1a(context);
-	      case 0x21: return do_int21(context);
-
-	      case 0x22:
-		AX = 0x1234;
-		BX = 0x5678;
-		CX = 0x9abc;
-		DX = 0xdef0;
-		return 1;
-
-              case 0x25: return do_int25(context);
-              case 0x26: return do_int26(context);
-              case 0x2a: return do_int2a(context);
-	      case 0x2f: return do_int2f(context);
-	      case 0x31: return do_int31(context);
-              case 0x3d: return 1;
-	      case 0x5c: return do_int5c(context);
-
-              default:
-                fprintf(stderr,"int%02x: Unimplemented!\n", intnum);
-                break;
-	}
-	return 0;
-}
-
-
 /***********************************************************************
  *           INSTR_EmulateInstruction
  *
@@ -62,35 +18,38 @@
  */
 BOOL INSTR_EmulateInstruction( struct sigcontext_struct *context )
 {
-    int prefix, segprefix, long_op, long_addr;
-    BYTE *instr = (BYTE *) PTR_SEG_OFF_TO_LIN( CS, IP );
+    int prefix, segprefix, repX, long_op, long_addr;
+    BYTE *instr;
+
+    long_op = long_addr = (GET_SEL_FLAGS(CS) & LDT_FLAGS_32BIT) != 0;
+    instr = (BYTE *) PTR_SEG_OFF_TO_LIN( CS, long_op ? EIP : IP );
 
     /* First handle any possible prefix */
 
-    long_op = long_addr = (GET_SEL_FLAGS(CS) & LDT_FLAGS_32BIT) != 0;
-    segprefix = 0;  /* no prefix */
+    segprefix = -1;  /* no prefix */
     prefix = 1;
+    repX = 0;
     while(prefix)
     {
         switch(*instr)
         {
         case 0x2e:
-            segprefix = 1;  /* CS */
+            segprefix = CS;
             break;
         case 0x36:
-            segprefix = 2;  /* SS */
+            segprefix = SS;
             break;
         case 0x3e:
-            segprefix = 3;  /* DS */
+            segprefix = DS;
             break;
         case 0x26:
-            segprefix = 4;  /* ES */
+            segprefix = ES;
             break;
         case 0x64:
-            segprefix = 5;  /* FS */
+            segprefix = FS;
             break;
         case 0x65:
-            segprefix = 6;  /* GS */
+            segprefix = GS;
             break;
         case 0x66:
             long_op = !long_op;  /* opcode size prefix */
@@ -99,8 +58,12 @@
             long_addr = !long_addr;  /* addr size prefix */
             break;
         case 0xf0:  /* lock */
+	    break;
         case 0xf2:  /* repne */
+	    repX = 1;
+	    break;
         case 0xf3:  /* repe */
+	    repX = 2;
             break;
         default:
             prefix = 0;  /* no more prefixes */
@@ -117,22 +80,33 @@
 
     switch(*instr)
     {
-      case 0xcd: /* int <XX> */
-            instr++;
-            /* FIXME: should check if handler has been changed */
-	    if (!do_int(*instr, context))
+        case 0xcd: /* int <XX> */
+            if (long_op)
             {
-		fprintf(stderr,"Unexpected Windows interrupt %x\n", *instr);
-                return FALSE;
-	    }
-	    EIP += 2;  /* Bypass the int instruction */
+                fprintf(stderr, "int xx from 32-bit code is not supported.\n");
+                return FALSE;  /* Unable to emulate it */
+            }
+            else
+            {
+                SEGPTR addr = INT_GetHandler( instr[1] );
+                /* FIXME: should check the stack 'big' bit */
+                WORD *stack = (WORD *)PTR_SEG_OFF_TO_LIN( SS, SP );
+                /* Push the flags and return address on the stack */
+                *(--stack) = FL;
+                *(--stack) = CS;
+                *(--stack) = IP + 2;
+                SP -= 3 * sizeof(WORD);
+                /* Jump to the interrupt handler */
+                CS  = HIWORD(addr);
+                EIP = LOWORD(addr);
+            }
             break;
 
-      case 0xcf: /* iret */
+        case 0xcf: /* iret */
             if (long_op)
             {
                 /* FIXME: should check the stack 'big' bit */
-                DWORD *stack = (WORD *)PTR_SEG_OFF_TO_LIN( SS, SP );
+                DWORD *stack = (DWORD *)PTR_SEG_OFF_TO_LIN( SS, SP );
                 EIP = *stack++;
                 CS  = *stack++;
                 EFL = *stack;
@@ -144,59 +118,135 @@
                 WORD *stack = (WORD *)PTR_SEG_OFF_TO_LIN( SS, SP );
                 EIP = *stack++;
                 CS  = *stack++;
-                EFL = (EFL & 0xffff0000) | *stack;
+                FL  = *stack;
                 SP += 3*sizeof(WORD);  /* Pop the return address and flags */
             }
             break;
 
-      case 0xe4: /* inb al,XX */
-            inportb_abs(context);
+        case 0xe4: /* inb al,XX */
+            AL = inport( instr[1], 1 );
 	    EIP += 2;
             break;
 
-      case 0xe5: /* in ax,XX */
-            inport_abs( context, long_op );
+        case 0xe5: /* in (e)ax,XX */
+            if (long_op) EAX = inport( instr[1], 4 );
+            else AX = inport( instr[1], 2 );
 	    EIP += 2;
             break;
 
-      case 0xe6: /* outb XX,al */
-            outportb_abs(context);
+        case 0xe6: /* outb XX,al */
+            outport( instr[1], 1, AL );
 	    EIP += 2;
             break;
 
-      case 0xe7: /* out XX,ax */
-            outport_abs( context, long_op );
-	    EIP += 2;
+        case 0xe7: /* out XX,(e)ax */
+            if (long_op) outport( instr[1], 4, EAX );
+            else outport( instr[1], 2, AX );
+  	    EIP += 2;
             break;
 
-      case 0xec: /* inb al,dx */
-            inportb(context);
+        case 0xec: /* inb al,dx */
+            AL = inport( DX, 1 );
 	    EIP++;
             break;
 
-      case 0xed: /* in ax,dx */
-            inport( context, long_op );
+        case 0xed: /* in (e)ax,dx */
+            if (long_op) EAX = inport( DX, 4 );
+            else AX = inport( DX, 2 );
 	    EIP++;  
             break;
 
-      case 0xee: /* outb dx,al */
-            outportb(context);
+        case 0xee: /* outb dx,al */
+            outport( DX, 1, AL );
 	    EIP++;
             break;
       
-      case 0xef: /* out dx,ax */
-            outport( context, long_op );
+        case 0xef: /* out dx,(e)ax */
+            if (long_op) outport( DX, 4, EAX );
+            else outport( DX, 2, AX );
 	    EIP++;
             break;
 
-      case 0xfa: /* cli, ignored */
+        case 0xfa: /* cli, ignored */
 	    EIP++;
             break;
 
-      case 0xfb: /* sti, ignored */
+        case 0xfb: /* sti, ignored */
 	    EIP++;
             break;
 
+        case 0x6c: /* insb     */
+        case 0x6d: /* insw/d   */
+        case 0x6e: /* outsb    */
+        case 0x6f: /* outsw/d  */
+	    {
+	      int typ = *instr;  /* Just in case it's overwritten.  */
+	      int outp = (typ >= 0x6e);
+	      unsigned long count = repX ? (long_addr ? ECX : CX) : 1;
+	      int opsize = (typ & 1) ? (long_op ? 4 : 2) : 1;
+	      int step = (EFL & 0x400) ? -opsize : +opsize;
+	      /* FIXME: Check this, please.  */
+	      int seg = outp ? (segprefix >= 0 ? segprefix : DS) : ES;
+
+	      if (outp)
+		/* FIXME: Check segment readable.  */
+		;
+	      else
+		/* FIXME: Check segment writeable.  */
+		;
+
+	      if (repX)
+		if (long_addr)
+		  ECX = 0;
+		else
+		  CX = 0;
+
+	      while (count-- > 0)
+		{
+		  void *data;
+		  if (outp)
+		    {
+		      data = PTR_SEG_OFF_TO_LIN (seg, long_addr ? ESI : SI);
+		      if (long_addr)
+			ESI += step;
+		      else
+			SI += step;
+		    }
+		  else
+		    {
+		      data = PTR_SEG_OFF_TO_LIN (seg, long_addr ? EDI : DI);
+		      if (long_addr)
+			EDI += step;
+		      else
+			DI += step;
+		    }
+
+		  switch (typ)
+		    {
+		    case 0x6c:
+		      *((BYTE *)data) = inport (DX, 1);
+		      break;
+		    case 0x6d:
+		      if (long_op)
+			*((DWORD *)data) = inport (DX, 4);
+		      else
+			*((WORD *)data) = inport (DX, 2);
+		      break;
+		    case 0x6e:
+		      outport (DX, 1, *((BYTE *)data));
+		      break;
+		    case 0x6f:
+		      if (long_op)
+			outport (DX, 4, *((DWORD *)data));
+		      else
+			outport (DX, 2, *((WORD *)data));
+		      break;
+		    }
+		}
+	      EIP++;
+	      break;
+	    }
+
       default:
             fprintf(stderr, "Unexpected Windows program segfault"
                             " - opcode = %x\n", *instr);
diff --git a/miscemu/int10.c b/miscemu/int10.c
index 501b183..04a1a87 100644
--- a/miscemu/int10.c
+++ b/miscemu/int10.c
@@ -7,38 +7,35 @@
 /* #define DEBUG_INT */
 #include "debug.h"
 
-void IntBarf(int i, struct sigcontext_struct *context)
+
+/**********************************************************************
+ *	    INT_Int10Handler
+ *
+ * Handler for int 10h (video).
+ */
+void INT_Int10Handler( struct sigcontext_struct sigcontext )
 {
-	dprintf_int(stddeb, "int%x: unknown/not implemented parameters:\n", i);
-	dprintf_int(stddeb, "int%x: AX %04x, BX %04x, CX %04x, DX %04x, "
-	       "SI %04x, DI %04x, DS %04x, ES %04x\n",
-	       i, AX, BX, CX, DX, SI, DI, DS, ES);
-}
+#define context (&sigcontext)
+    switch(AH)
+    {
+    case 0x0f:
+        AL = 0x5b;
+        break;
 
-int do_int10(struct sigcontext_struct *context)
-{
-        dprintf_int(stddeb,"int10: AX %04x, BX %04x, CX %04x, DX %04x, "
-               "SI %04x, DI %04x, DS %04x, ES %04x\n",
-               AX, BX, CX, DX, SI, DI, DS, ES);
-
-	switch(AH) {
-	case 0x0f:
-		AL = 0x5b;
-		break;
-
-	case 0x12:
-		if (BL == 0x10) {
-			BX = 0x0003;
-			CX = 0x0009;
-		}
-		break;
+    case 0x12:
+        if (BL == 0x10)
+        {
+            BX = 0x0003;
+            CX = 0x0009;
+        }
+        break;
 			
-	case 0x1a:
-		BX = 0x0008;
-		break;
+    case 0x1a:
+        BX = 0x0008;
+        break;
 
-	default:
-		IntBarf(0x10, context);
-	};
-	return 1;
+    default:
+        INT_BARF( 0x10 );
+    }
+#undef context
 }
diff --git a/miscemu/int13.c b/miscemu/int13.c
index e0e62f5..d570768 100644
--- a/miscemu/int13.c
+++ b/miscemu/int13.c
@@ -7,13 +7,17 @@
 /* #define DEBUG_INT */
 #include "debug.h"
 
-int do_int13(struct sigcontext_struct *context)
-{
-        dprintf_int(stddeb,"int13: AX %04x, BX %04x, CX %04x, DX %04x, "
-               "SI %04x, DI %04x, DS %04x, ES %04x\n",
-               AX, BX, CX, DX, SI, DI, DS, ES);
 
-	switch(AH) {
+/**********************************************************************
+ *	    INT_Int13Handler
+ *
+ * Handler for int 13h (disk I/O).
+ */
+void INT_Int13Handler( struct sigcontext_struct sigcontext )
+{
+#define context (&sigcontext)
+    switch(AH)
+    {
 	case 0x00:                            /* RESET DISK SYSTEM     */
 	case 0x04:                            /* VERIFY DISK SECTOR(S) */
 		AH = 0;
@@ -52,7 +56,7 @@
 		break;
 
 	default:
-		IntBarf(0x13, context);
-	};
-	return 1;
+		INT_BARF( 0x13 );
+    }
+#undef context
 }
diff --git a/miscemu/int15.c b/miscemu/int15.c
deleted file mode 100644
index 9efc47c..0000000
--- a/miscemu/int15.c
+++ /dev/null
@@ -1,19 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include "registers.h"
-#include "wine.h"
-#include "miscemu.h"
-#include "stddebug.h"
-/* #define DEBUG_INT */
-#include "debug.h"
-
-int do_int15(struct sigcontext_struct *context)
-{
-	switch(AH) {
-	case 0xc0:
-		
-	default:
-		IntBarf(0x15, context);
-	};
-	return 1;
-}
diff --git a/miscemu/int16.c b/miscemu/int16.c
deleted file mode 100644
index b3cc06e..0000000
--- a/miscemu/int16.c
+++ /dev/null
@@ -1,19 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include "registers.h"
-#include "wine.h"
-#include "miscemu.h"
-#include "stddebug.h"
-/* #define DEBUG_INT */
-#include "debug.h"
-
-int do_int16(struct sigcontext_struct *context)
-{
-	switch(AH) {
-	case 0xc0:
-		
-	default:
-		IntBarf(0x16, context);
-	};
-	return 1;
-}
diff --git a/miscemu/int1a.c b/miscemu/int1a.c
index 60a29ab..60cf634 100644
--- a/miscemu/int1a.c
+++ b/miscemu/int1a.c
@@ -13,16 +13,20 @@
 #define	BCD_TO_BIN(x) ((x&15) + (x>>4)*10)
 #define BIN_TO_BCD(x) ((x%10) + ((x/10)<<4))
 
-int do_int1a(struct sigcontext_struct * context){
+
+/**********************************************************************
+ *	    INT_Int1aHandler
+ *
+ * Handler for int 1ah (date and time).
+ */
+void INT_Int1aHandler( struct sigcontext_struct sigcontext )
+{
+#define context (&sigcontext)
 	time_t ltime;
         DWORD ticks;
 	struct tm *bdtime;
         struct timeval tvs;
 
-	dprintf_int(stddeb,"int1A: AX %04x, BX %04x, CX %04x, DX %04x, "
-	       "SI %04x, DI %04x, DS %04x, ES %04x\n",
-	       AX, BX, CX, DX, SI, DI, DS, ES);
-
 	switch(AH) {
 	case 0:
                 /* This should give us the (approximately) correct
@@ -68,8 +72,7 @@
 		break;
 
 	default:
-		IntBarf(0x1a, context);
-		return 1;
-	};
-	return 1;
+		INT_BARF( 0x1a );
+	}
+#undef context
 }
diff --git a/miscemu/int21.c b/miscemu/int21.c
index 078f34e..25b2f8c 100644
--- a/miscemu/int21.c
+++ b/miscemu/int21.c
@@ -24,7 +24,6 @@
 #include "options.h"
 #include "miscemu.h"
 #include "stddebug.h"
-/* #define DEBUG_INT */
 #include "debug.h"
 
 /* Define the drive parameter block, as used by int21/1F
@@ -196,7 +195,7 @@
 		return;
 	}
 
-	AX = 4;	
+	AX = (drive < 2) ? 1 : 64;  /* 64 for hard-disks, 1 for diskettes */
 	CX = 512;
 
 	BX = (available / (CX * AX));
@@ -206,8 +205,14 @@
 
 static void GetDriveAllocInfo(struct sigcontext_struct *context)
 {
+        int drive;
 	long size, available;
 	
+	if (DL == 0)
+		drive = DOS_GetDefaultDrive();
+	else
+		drive = DL - 1;
+
 	if (!DOS_ValidDrive(DL)) {
 		AX = 4;
 		CX = 512;
@@ -222,7 +227,7 @@
 		return;
 	}
 	
-	AX = 4;
+	AX = (drive < 2) ? 1 : 64;  /* 64 for hard-disks, 1 for diskettes */
 	CX = 512;
 	DX = (size / (CX * AX));
 
@@ -233,12 +238,6 @@
 	Error (0,0,0);
 }
 
-static void GetDefDriveAllocInfo(struct sigcontext_struct *context)
-{
-	DX = DOS_GetDefaultDrive();
-	GetDriveAllocInfo(context);
-}
-
 static void GetDrivePB(struct sigcontext_struct *context, int drive)
 {
         if(!DOS_ValidDrive(drive))
@@ -260,12 +259,12 @@
                 dpb->drive_num = dpb->unit_num = drive;    /* The same? */
                 dpb->sector_size = 512;
                 dpb->high_sector = 1;
-                dpb->shift = 0;
+                dpb->shift = drive < 2 ? 0 : 6; /* 6 for HD, 0 for floppy */
                 dpb->reserved = 0;
                 dpb->num_FAT = 1;
                 dpb->dir_entries = 2;
                 dpb->first_data = 2;
-                dpb->high_cluster = 1023;
+                dpb->high_cluster = 64000;
                 dpb->sectors_in_FAT = 1;
                 dpb->start_dir = 1;
                 dpb->driver_head = 0;
@@ -414,7 +413,7 @@
 	    
 		    if (fstat(BX, &sbuf) < 0)
 		    {
-			IntBarf(0x21, context);
+                        INT_BARF( 0x21 );
 			SetCflag;
 			return;
 		    }
@@ -444,8 +443,8 @@
 	}
 
 	if (CH != 0x08) {
-		IntBarf(0x21, context);
-		return;
+            INT_BARF( 0x21 );
+            return;
 	}
 	switch (CL) {
 		case 0x60: /* get device parameters */
@@ -469,7 +468,7 @@
 			ResetCflag;
 			return;
 		default:
-			IntBarf(0x21, context);
+                        INT_BARF( 0x21 );
 	}
 }
 
@@ -508,18 +507,18 @@
 
 static void CreateFile(struct sigcontext_struct *context)
 {
-	int handle;
-
-	if ((handle = open(DOS_GetUnixFileName( PTR_SEG_OFF_TO_LIN(DS,DX)), 
-           O_CREAT | O_TRUNC | O_RDWR )) == -1) {
-		errno_to_doserr();
-		AX = ExtendedError;
-		SetCflag;
-		return;
-		}			
-	Error (0,0,0);
-        AX = handle;
-	ResetCflag;
+    int handle;
+    handle = open(DOS_GetUnixFileName( PTR_SEG_OFF_TO_LIN(DS,DX)), 
+		  O_CREAT | O_TRUNC | O_RDWR, 0666 );
+    if (handle == -1) {
+	errno_to_doserr();
+	AX = ExtendedError;
+	SetCflag;
+	return;
+    }
+    Error (0,0,0);
+    AX = handle;
+    ResetCflag;
 }
 
 void OpenExistingFile(struct sigcontext_struct *context)
@@ -725,6 +724,7 @@
 
         memcpy(&dp, dta+0x11, sizeof(dp));
 
+        dprintf_int(stddeb, "int21: FindNext, dta %p, dp %p\n", dta, dp);
 	do {
 		if ((dp = DOS_readdir(dp)) == NULL) {
 			Error(NoMoreFiles, EC_MediaError , EL_Disk);
@@ -778,17 +778,6 @@
 	memset(dta + 1 , '?', 11);
 	*(dta + 0x0c) = ECX & (FA_LABEL | FA_DIREC);
 
-	if (ECX & FA_LABEL) {
-		/* return volume label */
-
-		if (DOS_GetVolumeLabel(drive) != NULL) 
-			strncpy(dta + 0x1e, DOS_GetVolumeLabel(drive), 8);
-
-		AX = 0;
-		ResetCflag;
-		return;
-	}
-
 	if ((dp = DOS_opendir(path)) == NULL) {
 		Error(PathNotFound, EC_MediaError, EL_Disk);
 		AX = FileNotFound;
@@ -841,7 +830,7 @@
 
 	dprintf_int(stddeb,"CreateTempFile %s\n",temp);
 
-	handle = open(DOS_GetUnixFileName(temp), O_CREAT | O_TRUNC | O_RDWR);
+	handle = open(DOS_GetUnixFileName(temp), O_CREAT | O_TRUNC | O_RDWR, 0666);
 
 	if (handle == -1) {
             Error( WriteProtected, EC_AccessDenied, EL_Disk );
@@ -860,7 +849,7 @@
 {
 	int handle;
 	
-	if ((handle = open(DOS_GetUnixFileName( PTR_SEG_OFF_TO_LIN(DS,DX) ), O_CREAT | O_EXCL | O_RDWR)) == -1) {
+	if ((handle = open(DOS_GetUnixFileName( PTR_SEG_OFF_TO_LIN(DS,DX) ), O_CREAT | O_EXCL | O_RDWR, 0666)) == -1) {
             Error( WriteProtected, EC_AccessDenied, EL_Disk );
             AX = WriteProtected;
             SetCflag;
@@ -1204,20 +1193,18 @@
 
 extern void LOCAL_PrintHeap (WORD ds);
 
-/************************************************************************/
-
-int do_int21(struct sigcontext_struct * context)
+/***********************************************************************
+ *           DOS3Call  (KERNEL.102)
+ */
+void DOS3Call( struct sigcontext_struct sigcontext )
 {
+#define context (&sigcontext)
     int drive;
 
-    dprintf_int(stddeb,"int21: AX %04x, BX %04x, CX %04x, DX %04x, "
-           "SI %04x, DI %04x, DS %04x, ES %04x\n",
-           AX, BX, CX, DX, SI, DI, DS, ES);
-
     if (AH == 0x59) 
     {
 	GetExtendedErrorInfo(context);
-	return 1;
+	return;
     } 
     else 
     {
@@ -1255,7 +1242,7 @@
 	  case 0x28: /* RANDOM BLOCK WRITE TO FCB FILE */
 	  case 0x29: /* PARSE FILENAME INTO FCB */
 	  case 0x2e: /* SET VERIFY FLAG */
-	    IntBarf(0x21, context);
+            INT_BARF( 0x21 );
 	    break;
 
 	  case 0x2b: /* SET SYSTEM DATE */
@@ -1264,7 +1251,7 @@
 			"SWITCHAR" - SET SWITCH CHARACTER
 			"AVAILDEV" - SPECIFY \DEV\ PREFIX USE */
 	  case 0x54: /* GET VERIFY FLAG */
-            IntBarf(0x21, context);
+            INT_BARF( 0x21 );
 	    break;
 
 	  case 0x18: /* NULL FUNCTIONS FOR CP/M COMPATIBILITY */
@@ -1284,15 +1271,14 @@
             break;
 
 	  case 0x0e: /* SELECT DEFAULT DRIVE */
-		if (!DOS_ValidDrive(DL)) {
-			Error (InvalidDrive, EC_MediaError, EL_Disk);
-			AX = MAX_DOS_DRIVES; 
-			break;
-		} else {
-			DOS_SetDefaultDrive(DL);
-			AX = MAX_DOS_DRIVES; 
-			Error(0,0,0);
+		if (!DOS_ValidDrive(DL))
+                    Error (InvalidDrive, EC_MediaError, EL_Disk);
+		else
+                {
+                    DOS_SetDefaultDrive(DL);
+                    Error(0,0,0);
 		}
+                AL = MAX_DOS_DRIVES;
 		break;
 
 	  case 0x11: /* FIND FIRST MATCHING FILE USING FCB */
@@ -1321,7 +1307,8 @@
             break;
 
 	  case 0x1b: /* GET ALLOCATION INFORMATION FOR DEFAULT DRIVE */
-	    GetDefDriveAllocInfo(context);
+            DL = 0;
+	    GetDriveAllocInfo(context);
 	    break;
 	
 	  case 0x1c: /* GET ALLOCATION INFORMATION FOR SPECIFIC DRIVE */
@@ -1359,7 +1346,7 @@
 	    break;
 
 	  case 0x31: /* TERMINATE AND STAY RESIDENT */
-            IntBarf(0x21, context);
+            INT_BARF( 0x21 );
 	    break;
 
 	  case 0x32: /* GET DOS DRIVE PARAMETER BLOCK FOR SPECIFIC DRIVE */
@@ -1390,7 +1377,7 @@
 		break;
 
 	      default:
-		IntBarf(0x21, context);
+                INT_BARF( 0x21 );
 		break;			
 	    }
 	    break;	
@@ -1541,7 +1528,7 @@
                 break;
                 
 	      default:
-                IntBarf(0x21, context);
+                INT_BARF( 0x21 );
 		break;
 	    }
 	    break;
@@ -1575,8 +1562,8 @@
 	  case 0x48: /* ALLOCATE MEMORY */
 	  case 0x49: /* FREE MEMORY */
 	  case 0x4a: /* RESIZE MEMORY BLOCK */
-	    IntBarf(0x21, context);
-	    break;
+            INT_BARF( 0x21 );
+            break;
 	
 	  case 0x4b: /* "EXEC" - LOAD AND/OR EXECUTE PROGRAM */
             WinExec( PTR_SEG_OFF_TO_LIN(DS,DX), SW_NORMAL );
@@ -1597,12 +1584,19 @@
 	  case 0x4f: /* "FINDNEXT" - FIND NEXT MATCHING FILE */
 	    FindNext(context);
 	    break;
-			
-	  case 0x52: /* "SYSVARS" - GET LIST OF LISTS */
-		ES = 0x0;
-		BX = 0x0;
-		IntBarf(0x21, context);
+
+	  case 0x51: /* GET PSP ADDRESS */
+	  case 0x62: /* GET PSP ADDRESS */
+	    /* FIXME: should we return the original DOS PSP upon */
+	    /*        Windows startup ? */
+	    BX = GetCurrentPDB();
 	    break;
+
+	  case 0x52: /* "SYSVARS" - GET LIST OF LISTS */
+            ES = 0x0;
+            BX = 0x0;
+            INT_BARF( 0x21 );
+            break;
 		
 	  case 0x56: /* "RENAME" - RENAME FILE */
 	    RenameFile(context);
@@ -1694,12 +1688,11 @@
 	    break;
 
 	  case 0x61: /* UNUSED */
-	  case 0x62: /* GET CURRENT PSP ADDRESS */
 	  case 0x63: /* UNUSED */
 	  case 0x64: /* OS/2 DOS BOX */
 	  case 0x65: /* GET EXTENDED COUNTRY INFORMATION */
-		IntBarf(0x21, context);
-	    break;
+            INT_BARF( 0x21 );
+            break;
 	
 	  case 0x66: /* GLOBAL CODE PAGE TABLE */
 	    switch (AL) {
@@ -1741,26 +1734,18 @@
 	    break;
 
 	  default:
-            IntBarf(0x21, context);
-	    return 1;
+            INT_BARF( 0x21 );
+            break;
 	}
     }
     dprintf_int(stddeb,"ret21: AX %04x, BX %04x, CX %04x, DX %04x, "
            "SI %04x, DI %04x, DS %04x, ES %04x EFL %08lx\n",
            AX, BX, CX, DX, SI, DI, DS, ES, EFL);
 
-    return 1;
+#undef context
 }
 
 
-/***********************************************************************
- *           DOS3Call  (KERNEL.102)
- */
-void DOS3Call( struct sigcontext_struct context )
-{
-    do_int21( &context );
-}
-
 void INT21_Init(void)
 {
     if ((DosHeapHandle = GlobalAlloc(GMEM_FIXED,sizeof(struct DosHeap))) == 0)
diff --git a/miscemu/int25.c b/miscemu/int25.c
index 6ebc32e..5427075 100644
--- a/miscemu/int25.c
+++ b/miscemu/int25.c
@@ -11,8 +11,14 @@
 /* #define DEBUG_INT */
 #include "debug.h"
 
-int do_int25(struct sigcontext_struct *context)
+/**********************************************************************
+ *	    INT_Int25Handler
+ *
+ * Handler for int 25h (absolute disk read).
+ */
+void INT_Int25Handler( struct sigcontext_struct sigcontext )
 {
+#define context (&sigcontext)
 	BYTE *dataptr = PTR_SEG_OFF_TO_LIN(DS, BX);
 	DWORD begin, length;
 
@@ -20,11 +26,7 @@
         {
             SetCflag;
             AX = 0x0101;        /* unknown unit */
-
-            /* push flags on stack */
-            SP -= sizeof(WORD);
-            setword(PTR_SEG_OFF_TO_LIN(SS,SP), (WORD) EFL);
-            return 1;
+            return;
         }
 
 	if (CX == 0xffff) {
@@ -48,10 +50,5 @@
 		*dataptr = 0xf8;
 
 	ResetCflag;
-
-	/* push flags on stack */
-	SP -= sizeof(WORD);
-	setword(PTR_SEG_OFF_TO_LIN(SS,SP), (WORD) EFL);
-
-	return 1;
+#undef context
 }
diff --git a/miscemu/int26.c b/miscemu/int26.c
index 97bf02d..aa281d7 100644
--- a/miscemu/int26.c
+++ b/miscemu/int26.c
@@ -10,8 +10,14 @@
 /* #define DEBUG_INT */
 #include "debug.h"
 
-int do_int26(struct sigcontext_struct *context)
+/**********************************************************************
+ *	    INT_Int26Handler
+ *
+ * Handler for int 26h (absolute disk read).
+ */
+void INT_Int26Handler( struct sigcontext_struct sigcontext )
 {
+#define context (&sigcontext)
 	BYTE *dataptr = PTR_SEG_OFF_TO_LIN(DS, BX);
 	DWORD begin, length;
 
@@ -19,11 +25,7 @@
         {
             SetCflag;
             AX = 0x0101;        /* unknown unit */
-
-            /* push flags on stack */
-            SP -= sizeof(WORD);
-            setword(PTR_SEG_OFF_TO_LIN(SS,SP), (WORD) EFL);
-            return 1;
+            return;
         }
 
 	if (CX == 0xffff) {
@@ -40,10 +42,5 @@
 	"count %ld, buffer %d\n", AL, begin, length, (int) dataptr);
 
 	ResetCflag;
-
-	/* push flags on stack */
-	SP -= sizeof(WORD);
-	setword(PTR_SEG_OFF_TO_LIN(SS,SP), (WORD) EFL);
-
-	return 1;
+#undef context
 }
diff --git a/miscemu/int2a.c b/miscemu/int2a.c
index 63ed11d..35921fb 100644
--- a/miscemu/int2a.c
+++ b/miscemu/int2a.c
@@ -2,20 +2,27 @@
 #include <stdlib.h>
 #include "msdos.h"
 #include "wine.h"
+#include "registers.h"
 #include "miscemu.h"
 #include "stddebug.h"
 /* #define DEBUG_INT */
 #include "debug.h"
 
-int do_int2a(struct sigcontext_struct *context)
+/**********************************************************************
+ *	    INT_Int2aHandler
+ *
+ * Handler for int 2ah (network).
+ */
+void INT_Int2aHandler( struct sigcontext_struct sigcontext )
 {
-	switch((context->sc_eax >> 8) & 0xff)
-	{
-	case 0x00:                             /* NETWORK INSTALLATION CHECK */
-		break;
+#define context (&sigcontext)
+    switch(AH)
+    {
+    case 0x00:                             /* NETWORK INSTALLATION CHECK */
+        break;
 		
-	default:
-		IntBarf(0x2a, context);
-	};
-	return 1;
+    default:
+	INT_BARF( 0x2a );
+    }
+#undef context
 }
diff --git a/miscemu/int2f.c b/miscemu/int2f.c
index ad797d1..88bd229 100644
--- a/miscemu/int2f.c
+++ b/miscemu/int2f.c
@@ -9,35 +9,37 @@
 /* #define DEBUG_INT */
 #include "debug.h"
 
-int do_int2f_16(struct sigcontext_struct *context);
+static void do_int2f_16(struct sigcontext_struct *context);
 
-int do_int2f(struct sigcontext_struct *context)
+/**********************************************************************
+ *	    INT_Int2fHandler
+ *
+ * Handler for int 2fh (multiplex).
+ */
+void INT_Int2fHandler( struct sigcontext_struct sigcontext )
 {
-        dprintf_int(stddeb,"int2f: AX %04x, BX %04x, CX %04x, DX %04x, "
-               "SI %04x, DI %04x, DS %04x, ES %04x\n",
-               AX, BX, CX, DX, SI, DI, DS, ES);
-
-	switch(AH)
-	{
+#define context (&sigcontext)
+    switch(AH)
+    {
 	case 0x10:
                 AL = 0xff; /* share is installed */
 		break;
 
 	case 0x15: /* mscdex */
 		/* ignore requests */
-		return 1;
+		break;
 
 	case 0x16:
-		return do_int2f_16(context);
-
+		do_int2f_16( context );
+                break;
 	default:
-		IntBarf(0x2f, context);
-	};
-	return 1;
+		INT_BARF( 0x2f );
+            }
+#undef context
 }
 
 
-int do_int2f_16(struct sigcontext_struct *context)
+static void do_int2f_16(struct sigcontext_struct *context)
 {
     switch(AL)
     {
@@ -51,6 +53,9 @@
         CX = Options.enhanced ? 3 : 2;
         break;
 
+    case 0x80:  /* Release time-slice */
+        break;  /* nothing to do */
+
     case 0x86:  /* DPMI detect mode */
         AX = 0;  /* Running under DPMI */
         break;
@@ -58,17 +63,16 @@
     case 0x87:  /* DPMI installation check */
         AX = 0x0000;  /* DPMI Installed */
         BX = 0x0001;  /* 32bits available */
-        CX = 0x04;    /* processor 486 */
-        DX = 0x0009;  /* DPMI major/minor 0.9 */
+        CL = 0x03;    /* processor 386 */
+        DX = 0x005a;  /* DPMI major/minor 0.90 */
         SI = 0;       /* # of para. of DOS extended private data */
         ES = 0;       /* ES:DI is DPMI switch entry point */
         DI = 0;
         break;
 
     default:
-        IntBarf(0x2f, context);
+        INT_BARF( 0x2f );
     }
-    return 1;
 }
 
 
diff --git a/miscemu/int5c.c b/miscemu/int5c.c
index 0bd1fd1..ad94c25 100644
--- a/miscemu/int5c.c
+++ b/miscemu/int5c.c
@@ -13,21 +13,13 @@
 
 
 /***********************************************************************
- *           do_int5c
- */
-int do_int5c(struct sigcontext_struct * context)
-{
-    dprintf_int(stddeb,"NetBiosCall: AX %04x, BX %04x, CX %04x, DX %04x, "
-           "SI %04x, DI %04x, DS %04x, ES %04x\n",
-           AX, BX, CX, DX, SI, DI, DS, ES);
-    return 0;
-}
-
-
-/***********************************************************************
  *           NetBIOSCall  (KERNEL.103)
+ *
+ * Also handler for interrupt 5c.
  */
-void NetBIOSCall( struct sigcontext_struct context )
+void NetBIOSCall( struct sigcontext_struct sigcontext )
 {
-    do_int5c( &context );
+#define context (&sigcontext)
+    INT_BARF( 0x5c );
+#undef context
 }
diff --git a/miscemu/interrupts.c b/miscemu/interrupts.c
index 01f957e..b576424 100644
--- a/miscemu/interrupts.c
+++ b/miscemu/interrupts.c
@@ -6,7 +6,10 @@
 
 #include "windows.h"
 #include "miscemu.h"
+#include "dos_fs.h"
 #include "module.h"
+#include "registers.h"
+#include "stackframe.h"
 #include "stddebug.h"
 #include "debug.h"
 
@@ -21,15 +24,17 @@
  */
 BOOL INT_Init(void)
 {
-    SEGPTR addr, dummyHandler;
     WORD vector;
     HMODULE hModule = GetModuleHandle( "WINPROCS" );
 
-    dummyHandler = MODULE_GetEntryPoint( hModule, FIRST_INTERRUPT_ORDINAL+256);
     for (vector = 0; vector < 256; vector++)
     {
-        addr = MODULE_GetEntryPoint( hModule, FIRST_INTERRUPT_ORDINAL+vector );
-        INT_Vectors[vector] = addr ? addr : dummyHandler;
+        if (!(INT_Vectors[vector] = MODULE_GetEntryPoint( hModule,
+		                             FIRST_INTERRUPT_ORDINAL+vector )))
+	{
+	    fprintf(stderr,"Internal error: no vector for int %02x\n",vector);
+	    return FALSE;
+	}
     }
     return TRUE;
 }
@@ -42,9 +47,6 @@
  */
 SEGPTR INT_GetHandler( BYTE intnum )
 {
-    dprintf_int( stddeb, "Get interrupt vector %02x -> %04x:%04x\n",
-                 intnum, HIWORD(INT_Vectors[intnum]),
-                 LOWORD(INT_Vectors[intnum]) );
     return INT_Vectors[intnum];
 }
 
@@ -65,126 +67,61 @@
 /**********************************************************************
  *	    INT_DummyHandler
  */
-void INT_DummyHandler( struct sigcontext_struct context )
+void INT_DummyHandler( struct sigcontext_struct sigcontext )
 {
-    dprintf_int( stddeb, "Dummy handler called!\n" );
-}
-
-/**********************************************************************
- *	    INT_Int10Handler
- */
-void INT_Int10Handler( struct sigcontext_struct context )
-{
-    dprintf_int( stddeb, "int 10 called indirectly through handler!\n" );
-    do_int10( &context );
+#define context (&sigcontext)
+    INT_BARF( CURRENT_STACK16->ordinal_number - FIRST_INTERRUPT_ORDINAL );
+#undef context
 }
 
 
 /**********************************************************************
- *	    INT_Int13Handler
+ *	    INT_Int11Handler
+ *
+ * Handler for int 11h (get equipment list).
  */
-void INT_Int13Handler( struct sigcontext_struct context )
+void INT_Int11Handler( struct sigcontext_struct sigcontext )
 {
-    dprintf_int( stddeb, "int 13 called indirectly through handler!\n" );
-    do_int13( &context );
+#define context (&sigcontext)
+    AX = DOS_GetEquipment();
+#undef context
+}
+
+
+/**********************************************************************
+ *	    INT_Int12Handler
+ *
+ * Handler for int 12h (get memory size).
+ */
+void INT_Int12Handler( struct sigcontext_struct sigcontext )
+{
+#define context (&sigcontext)
+    AX = 640;
+#undef context
 }
 
 
 /**********************************************************************
  *	    INT_Int15Handler
+ *
+ * Handler for int 15h.
  */
-void INT_Int15Handler( struct sigcontext_struct context )
+void INT_Int15Handler( struct sigcontext_struct sigcontext )
 {
-    dprintf_int( stddeb, "int 15 called indirectly through handler!\n" );
-    do_int15( &context );
+#define context (&sigcontext)
+    INT_BARF( 0x15 );
+#undef context
 }
 
 
 /**********************************************************************
  *	    INT_Int16Handler
+ *
+ * Handler for int 16h (keyboard).
  */
-void INT_Int16Handler( struct sigcontext_struct context )
+void INT_Int16Handler( struct sigcontext_struct sigcontext )
 {
-    dprintf_int( stddeb, "int 16 called indirectly through handler!\n" );
-    do_int16( &context );
-}
-
-
-/**********************************************************************
- *	    INT_Int1aHandler
- */
-void INT_Int1aHandler( struct sigcontext_struct context )
-{
-    dprintf_int( stddeb, "int 1a called indirectly through handler!\n" );
-    do_int1a( &context );
-}
-
-
-/**********************************************************************
- *	    INT_Int21Handler
- */
-void INT_Int21Handler( struct sigcontext_struct context )
-{
-    dprintf_int( stddeb, "int 21 called indirectly through handler!\n" );
-    do_int21( &context );
-}
-
-
-/**********************************************************************
- *	    INT_Int25Handler
- */
-void INT_Int25Handler( struct sigcontext_struct context )
-{
-    dprintf_int( stddeb, "int 25 called indirectly through handler!\n" );
-    do_int25( &context );
-}
-
-
-/**********************************************************************
- *	    INT_Int26Handler
- */
-void INT_Int26Handler( struct sigcontext_struct context )
-{
-    dprintf_int( stddeb, "int 26 called indirectly through handler!\n" );
-    do_int26( &context );
-}
-
-
-/**********************************************************************
- *	    INT_Int2aHandler
- */
-void INT_Int2aHandler( struct sigcontext_struct context )
-{
-    dprintf_int( stddeb, "int 2a called indirectly through handler!\n" );
-    do_int2a( &context );
-}
-
-
-/**********************************************************************
- *	    INT_Int2fHandler
- */
-void INT_Int2fHandler( struct sigcontext_struct context )
-{
-    dprintf_int( stddeb, "int 2f called indirectly through handler!\n" );
-    do_int2f( &context );
-}
-
-
-/**********************************************************************
- *	    INT_Int31Handler
- */
-void INT_Int31Handler( struct sigcontext_struct context )
-{
-    dprintf_int( stddeb, "int 31 called indirectly through handler!\n" );
-    do_int31( &context );
-}
-
-
-/**********************************************************************
- *	    INT_Int5cHandler
- */
-void INT_Int5cHandler( struct sigcontext_struct context )
-{
-    dprintf_int( stddeb, "int 5c called indirectly through handler!\n" );
-    do_int5c( &context );
+#define context (&sigcontext)
+    INT_BARF( 0x16 );
+#undef context
 }
diff --git a/miscemu/ioports.c b/miscemu/ioports.c
index 161ca06..3ea012a 100644
--- a/miscemu/ioports.c
+++ b/miscemu/ioports.c
@@ -1,87 +1,86 @@
+/*
+ * Emulation of processor ioports.
+ *
+ * Copyright 1995 Morten Welinder
+ */
+
+/* Known problems:
+   - only a few ports are emulated.
+   - real-time clock in "cmos" is bogus.  A nifty alarm() setup could
+     fix that, I guess.
+*/
+
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <time.h>
-#include "registers.h"
-#include "wine.h"
+#include "windows.h"
 #include "stddebug.h"
 /* #define DEBUG_INT */
 #include "debug.h"
 
 static BYTE cmosaddress;
 
-static BYTE cmosimage[64] = {
-	0x27, 0x34, 0x31, 0x47, 0x16, 0x15, 0x00, 0x01,
-	0x04, 0x94, 0x26, 0x02, 0x50, 0x80, 0x00, 0x00,
-	0x40, 0xb1, 0x00, 0x9c, 0x01, 0x80, 0x02, 0x00,
-	0x1c, 0x00, 0x00, 0xad, 0x02, 0x10, 0x00, 0x00,
-	0x08, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x03, 0x58,
-	0x00, 0x1c, 0x19, 0x81, 0x00, 0x0e, 0x00, 0x80,
-	0x1b, 0x7b, 0x21, 0x00, 0x00, 0x00, 0x05, 0x5f };
-
-void inportb(struct sigcontext_struct *context)
+static BYTE cmosimage[64] =
 {
-	dprintf_int(stddeb, "IO: inb (%x)\n", DX);
+  0x27, 0x34, 0x31, 0x47, 0x16, 0x15, 0x00, 0x01,
+  0x04, 0x94, 0x26, 0x02, 0x50, 0x80, 0x00, 0x00,
+  0x40, 0xb1, 0x00, 0x9c, 0x01, 0x80, 0x02, 0x00,
+  0x1c, 0x00, 0x00, 0xad, 0x02, 0x10, 0x00, 0x00,
+  0x08, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x03, 0x58,
+  0x00, 0x1c, 0x19, 0x81, 0x00, 0x0e, 0x00, 0x80,
+  0x1b, 0x7b, 0x21, 0x00, 0x00, 0x00, 0x05, 0x5f
+};
 
-	switch(DX) {
-		case 0x70:
-			AL = cmosaddress;
-			break;
-		case 0x71:
-			AL = cmosimage[cmosaddress & 0x3f];
-			break;
-		default:
-	}
-}
 
-void inport( struct sigcontext_struct *context, int long_op )
+DWORD inport( int port, int count )
 {
-    dprintf_int(stdnimp, "IO: in (%x)\n", DX);
-    if (long_op) EAX = 0xffffffff;
-    else AX = 0xffff;
-}
+    DWORD res = 0;
+    BYTE b;
 
-void inportb_abs(struct sigcontext_struct *context)
-{
-	dprintf_int(stdnimp, "IO: in (%x)\n", *(BYTE *)(EIP+1));
-	AL = 0xff;
-}
+    dprintf_int(stddeb, "IO: %d bytes from port 0x%02x\n", count, port );
 
-void inport_abs( struct sigcontext_struct *context, int long_op )
-{
-    dprintf_int(stdnimp, "IO: in (%x)\n", *(BYTE *)(EIP+1));
-    if (long_op) EAX = 0xffffffff;
-    else AX = 0xffff;
-}
-
-void outportb(struct sigcontext_struct *context)
-{
-	dprintf_int(stdnimp, "IO: outb (%x), %x\n", DX, AX);
-
-	switch (EDX & 0xffff)
+    while (count-- > 0)
+    {
+        switch (port++)
 	{
-		case 0x70:
-			cmosaddress = AL & 0x7f;
-			break;
-		case 0x71:
-			cmosimage[cmosaddress & 0x3f] = AL;
-			break;
-		default:
+	case 0x70:
+            b = cmosaddress;
+            break;
+	case 0x71:
+            b = cmosimage[cmosaddress & 0x3f];
+            break;
+	default:
+	  b = 0xff;
 	}
+        res = (res << 8) | b;
+    }
+    return res;
 }
 
-void outport( struct sigcontext_struct *context, int long_op )
-{
-    dprintf_int(stdnimp, "IO: out (%x), %lx\n", DX, long_op ? EAX : AX);
-}
 
-void outportb_abs(struct sigcontext_struct *context)
+void outport( int port, int count, DWORD value )
 {
-    dprintf_int(stdnimp, "IO: out (%x), %x\n", *(BYTE *)(EIP+1), AL);
-}
+    BYTE b;
 
-void outport_abs( struct sigcontext_struct *context, int long_op )
-{
-    dprintf_int(stdnimp, "IO: out (%x), %lx\n", *(BYTE *)(EIP+1),
-                long_op ? EAX : AX);
+    dprintf_int( stddeb, "IO: 0x%lx (%d bytes) to port 0x%02x\n",
+                 value, count, port );
+
+    while (count-- > 0)
+    {
+        b = value & 0xff;
+        value >>= 8;
+        switch (port++)
+	{
+	case 0x70:
+            cmosaddress = b & 0x7f;
+            break;
+	case 0x71:
+            cmosimage[cmosaddress & 0x3f] = b;
+            break;
+	default:
+            /* Rien du tout.  */
+	}
+    }
 }