Index: dosbox-0.74/src/ints/mouse.cpp
===================================================================
--- dosbox-0.74.orig/src/ints/mouse.cpp	2010-12-31 03:26:16.000000000 +0100
+++ dosbox-0.74/src/ints/mouse.cpp	2010-12-31 03:28:38.000000000 +0100
@@ -36,7 +36,7 @@
 
 static Bitu call_int33,call_int74,int74_ret_callback,call_mouse_bd;
 static Bit16u ps2cbseg,ps2cbofs;
-static bool useps2callback,ps2callbackinit;
+static bool useps2callback,ps2callbackinit,ps2callbacktablet;
 static Bitu call_ps2;
 static RealPt ps2_callback;
 static Bit16s oldmouseX, oldmouseY;
@@ -90,6 +90,7 @@
 	float add_x,add_y;
 	Bit16s min_x,max_x,min_y,max_y;
 	float mickey_x,mickey_y;
+	float real_x, real_y;
 	float x,y;
 	button_event event_queue[QUEUE_SIZE];
 	Bit8u events;//Increase if QUEUE_SIZE >255 (currently 32)
@@ -136,11 +137,18 @@
 		return false;
 	}
 	useps2callback = use;
+	if (!use) {
+		ps2callbacktablet = false;
+	}
 	Mouse_AutoLock(useps2callback);
 	PIC_SetIRQMask(MOUSE_IRQ,!useps2callback);
 	return true;
 }
 
+void Mouse_SetPS2AbsMode(bool use) {
+	ps2callbacktablet = use;
+}
+
 void Mouse_ChangePS2Callback(Bit16u pseg, Bit16u pofs) {
 	if ((pseg==0) && (pofs==0)) {
 		ps2callbackinit = false;
@@ -172,10 +180,21 @@
 			ydiff = (0x100+ydiff);
 			mdat |= 0x20;
 		}
-		CPU_Push16((Bit16u)mdat); 
-		CPU_Push16((Bit16u)(xdiff % 256)); 
-		CPU_Push16((Bit16u)(ydiff % 256)); 
-		CPU_Push16((Bit16u)0); 
+		if (ps2callbacktablet) {
+			Bit16u xabs = mouse.real_x * 65535.0;
+			Bit16u yabs = mouse.real_y * 65535.0;
+			mdat = (data & 0x3) | 0x4; // Set the ficticious "tablet bit".
+			if (xdiff || ydiff) mdat |= 0x8;
+			CPU_Push16((Bit16u)mdat);
+			CPU_Push16((Bit16u)xabs);
+			CPU_Push16((Bit16u)yabs);
+			CPU_Push16((Bit16u)0);
+		} else {
+			CPU_Push16((Bit16u)mdat);
+			CPU_Push16((Bit16u)(xdiff % 256));
+			CPU_Push16((Bit16u)(ydiff % 256));
+			CPU_Push16((Bit16u)0);
+		}
 		CPU_Push16(RealSeg(ps2_callback));
 		CPU_Push16(RealOff(ps2_callback));
 		SegSet16(cs, ps2cbseg);
@@ -456,6 +475,9 @@
 
 	mouse.mickey_x += dx;
 	mouse.mickey_y += dy;
+	mouse.real_x = x;
+	mouse.real_y = y;
+#if 0
 	if (emulate) {
 		mouse.x += dx;
 		mouse.y += dy;
@@ -476,6 +498,10 @@
 			mouse.y += yrel;
 		}
 	}
+#else
+	mouse.x = mouse.min_x + x * mouse.max_x;
+	mouse.y = mouse.min_y + y * mouse.max_y;
+#endif
 
 	/* ignore constraints if using PS2 mouse callback in the bios */
 
@@ -922,6 +948,9 @@
 		reg_cx=(Bit16u)mouse.max_x;
 		reg_dx=(Bit16u)mouse.max_y;
 		break;
+	case 0x64:
+		Mouse_SetPS2AbsMode(reg_bx);
+		break;
 	default:
 		LOG(LOG_MOUSE,LOG_ERROR)("Mouse Function %04X not implemented!",reg_ax);
 		break;
@@ -1081,7 +1110,7 @@
 	RealSetVec(hwvec,CALLBACK_RealPointer(call_int74));
 
 	// Callback for ps2 user callback handling
-	useps2callback = false; ps2callbackinit = false;
+	useps2callback = false; ps2callbackinit = false; ps2callbacktablet = false;
  	call_ps2=CALLBACK_Allocate();
 	CALLBACK_Setup(call_ps2,&PS2_Handler,CB_RETF,"ps2 bios callback");
 	ps2_callback=CALLBACK_RealPointer(call_ps2);
Index: dosbox-0.74/include/mouse.h
===================================================================
--- dosbox-0.74.orig/include/mouse.h	2010-12-31 03:26:16.000000000 +0100
+++ dosbox-0.74/include/mouse.h	2010-12-31 03:28:38.000000000 +0100
@@ -27,7 +27,7 @@
 void Mouse_HideCursor(void);
 
 bool Mouse_SetPS2State(bool use);
-
+void Mouse_SetPS2AbsMode(bool use);
 void Mouse_ChangePS2Callback(Bit16u pseg, Bit16u pofs);
 
 
Index: dosbox-0.74/src/ints/bios.cpp
===================================================================
--- dosbox-0.74.orig/src/ints/bios.cpp	2010-12-31 03:26:15.000000000 +0100
+++ dosbox-0.74/src/ints/bios.cpp	2010-12-31 03:28:38.000000000 +0100
@@ -776,6 +776,11 @@
 			CALLBACK_SCF(false);
 			reg_ah=0;
 			break;
+		case 0x10:		// set tablet
+			Mouse_SetPS2AbsMode(reg_bh);
+			CALLBACK_SCF(false);
+			reg_ah=0;
+			break;
 		default:
 			CALLBACK_SCF(true);
 			reg_ah=1;
