Acknowledge mouse interrupt before entering user routine; fixes sound stutter during mouse movement in Eye of the Beholder III and Casino Tournament of Champions. Clear button counters in the mouse driver reset function; prevents unintended skipping of intro in MechWarrior and others.
Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4188
This commit is contained in:
		
							parent
							
								
									d4c38121c9
								
							
						
					
					
						commit
						64d25c4be4
					
				
					 4 changed files with 85 additions and 34 deletions
				
			
		|  | @ -27,7 +27,8 @@ | |||
| typedef Bitu (*CallBack_Handler)(void); | ||||
| extern CallBack_Handler CallBack_Handlers[]; | ||||
| 
 | ||||
| enum { CB_RETN,CB_RETF,CB_RETF8,CB_IRET,CB_IRETD,CB_IRET_STI,CB_IRET_EOI_PIC1, | ||||
| enum { CB_RETN,CB_RETF,CB_RETF8,CB_RETF_STI,CB_RETF_CLI, | ||||
| 		CB_IRET,CB_IRETD,CB_IRET_STI,CB_IRET_EOI_PIC1, | ||||
| 		CB_IRQ0,CB_IRQ1,CB_IRQ9,CB_IRQ12,CB_IRQ12_RET,CB_IRQ6_PCJR,CB_MOUSE, | ||||
| 		CB_INT29,CB_INT16,CB_HOOKABLE,CB_TDE_IRET,CB_IPXESR,CB_IPXESR_RET, | ||||
| 		CB_INT21,CB_INT13,CB_VESA_WAIT,CB_VESA_PM }; | ||||
|  |  | |||
|  | @ -173,6 +173,26 @@ Bitu CALLBACK_SetupExtra(Bitu callback, Bitu type, PhysPt physAddress, bool use_ | |||
| 		phys_writeb(physAddress+0x00,(Bit8u)0xCA);		//A RETF 8 Instruction
 | ||||
| 		phys_writew(physAddress+0x01,(Bit16u)0x0008); | ||||
| 		return (use_cb?7:3); | ||||
| 	case CB_RETF_STI: | ||||
| 		phys_writeb(physAddress+0x00,(Bit8u)0xFB);		//STI
 | ||||
| 		if (use_cb) { | ||||
| 			phys_writeb(physAddress+0x01,(Bit8u)0xFE);	//GRP 4
 | ||||
| 			phys_writeb(physAddress+0x02,(Bit8u)0x38);	//Extra Callback instruction
 | ||||
| 			phys_writew(physAddress+0x03,(Bit16u)callback);	//The immediate word
 | ||||
| 			physAddress+=4; | ||||
| 		} | ||||
| 		phys_writeb(physAddress+0x01,(Bit8u)0xCB);		//A RETF Instruction
 | ||||
| 		return (use_cb?6:2); | ||||
| 	case CB_RETF_CLI: | ||||
| 		phys_writeb(physAddress+0x00,(Bit8u)0xFA);		//CLI
 | ||||
| 		if (use_cb) { | ||||
| 			phys_writeb(physAddress+0x01,(Bit8u)0xFE);	//GRP 4
 | ||||
| 			phys_writeb(physAddress+0x02,(Bit8u)0x38);	//Extra Callback instruction
 | ||||
| 			phys_writew(physAddress+0x03,(Bit16u)callback);	//The immediate word
 | ||||
| 			physAddress+=4; | ||||
| 		} | ||||
| 		phys_writeb(physAddress+0x01,(Bit8u)0xCB);		//A RETF Instruction
 | ||||
| 		return (use_cb?6:2); | ||||
| 	case CB_IRET: | ||||
| 		if (use_cb) { | ||||
| 			phys_writeb(physAddress+0x00,(Bit8u)0xFE);	//GRP 4
 | ||||
|  | @ -282,26 +302,32 @@ Bitu CALLBACK_SetupExtra(Bitu callback, Bitu type, PhysPt physAddress, bool use_ | |||
| 		return (use_cb?0x0e:0x0a); | ||||
| 	case CB_IRQ12:	// ps2 mouse int74
 | ||||
| 		if (!use_cb) E_Exit("int74 callback must implement a callback handler!"); | ||||
| 		phys_writeb(physAddress+0x00,(Bit8u)0x1e);		// push ds
 | ||||
| 		phys_writeb(physAddress+0x01,(Bit8u)0x06);		// push es
 | ||||
| 		phys_writew(physAddress+0x02,(Bit16u)0x6066);	// pushad
 | ||||
| 		phys_writeb(physAddress+0x04,(Bit8u)0xfc);		// cld
 | ||||
| 		phys_writeb(physAddress+0x05,(Bit8u)0xfb);		// sti
 | ||||
| 		phys_writeb(physAddress+0x06,(Bit8u)0xFE);		//GRP 4
 | ||||
| 		phys_writeb(physAddress+0x07,(Bit8u)0x38);		//Extra Callback instruction
 | ||||
| 		phys_writew(physAddress+0x08,(Bit16u)callback);			//The immediate word
 | ||||
| 		return 0x0a; | ||||
| 		phys_writeb(physAddress+0x00,(Bit8u)0xfb);		// sti
 | ||||
| 		phys_writeb(physAddress+0x01,(Bit8u)0x1e);		// push ds
 | ||||
| 		phys_writeb(physAddress+0x02,(Bit8u)0x06);		// push es
 | ||||
| 		phys_writew(physAddress+0x03,(Bit16u)0x6066);	// pushad
 | ||||
| 		phys_writeb(physAddress+0x05,(Bit8u)0xFE);		//GRP 4
 | ||||
| 		phys_writeb(physAddress+0x06,(Bit8u)0x38);		//Extra Callback instruction
 | ||||
| 		phys_writew(physAddress+0x07,(Bit16u)callback);			//The immediate word
 | ||||
| 		phys_writeb(physAddress+0x09,(Bit8u)0x50);		// push ax
 | ||||
| 		phys_writew(physAddress+0x0a,(Bit16u)0x20b0);	// mov al, 0x20
 | ||||
| 		phys_writew(physAddress+0x0c,(Bit16u)0xa0e6);	// out 0xa0, al
 | ||||
| 		phys_writew(physAddress+0x0e,(Bit16u)0x20e6);	// out 0x20, al
 | ||||
| 		phys_writeb(physAddress+0x10,(Bit8u)0x58);		// pop ax
 | ||||
| 		phys_writeb(physAddress+0x11,(Bit8u)0xfc);		// cld
 | ||||
| 		phys_writeb(physAddress+0x12,(Bit8u)0xCB);		//A RETF Instruction
 | ||||
| 		return 0x13; | ||||
| 	case CB_IRQ12_RET:	// ps2 mouse int74 return
 | ||||
| 		if (use_cb) { | ||||
| 			phys_writeb(physAddress+0x00,(Bit8u)0xFE);	//GRP 4
 | ||||
| 			phys_writeb(physAddress+0x01,(Bit8u)0x38);	//Extra Callback instruction
 | ||||
| 			phys_writew(physAddress+0x02,(Bit16u)callback);		//The immediate word
 | ||||
| 			physAddress+=4; | ||||
| 		} | ||||
| 		phys_writeb(physAddress+0x00,(Bit8u)0xfa);		// cli
 | ||||
| 		phys_writew(physAddress+0x01,(Bit16u)0x20b0);	// mov al, 0x20
 | ||||
| 		phys_writew(physAddress+0x03,(Bit16u)0xa0e6);	// out 0xa0, al
 | ||||
| 		phys_writew(physAddress+0x05,(Bit16u)0x20e6);	// out 0x20, al
 | ||||
| 		if (use_cb) { | ||||
| 			phys_writeb(physAddress+0x07,(Bit8u)0xFE);	//GRP 4
 | ||||
| 			phys_writeb(physAddress+0x08,(Bit8u)0x38);	//Extra Callback instruction
 | ||||
| 			phys_writew(physAddress+0x09,(Bit16u)callback);		//The immediate word
 | ||||
| 			physAddress+=4; | ||||
| 		} | ||||
| 		phys_writew(physAddress+0x07,(Bit16u)0x6166);	// popad
 | ||||
| 		phys_writeb(physAddress+0x09,(Bit8u)0x07);		// pop es
 | ||||
| 		phys_writeb(physAddress+0x0a,(Bit8u)0x1f);		// pop ds
 | ||||
|  |  | |||
|  | @ -1190,7 +1190,6 @@ static Bitu DOS_25Handler(void) { | |||
| 		SETFLAGBIT(CF,false); | ||||
| 		reg_ax = 0; | ||||
| 	} | ||||
| 	SETFLAGBIT(IF,true); | ||||
|     return CBRET_NONE; | ||||
| } | ||||
| static Bitu DOS_26Handler(void) { | ||||
|  | @ -1202,7 +1201,6 @@ static Bitu DOS_26Handler(void) { | |||
| 		SETFLAGBIT(CF,false); | ||||
| 		reg_ax = 0; | ||||
| 	} | ||||
| 	SETFLAGBIT(IF,true); | ||||
|     return CBRET_NONE; | ||||
| } | ||||
| 
 | ||||
|  | @ -1223,10 +1221,10 @@ public: | |||
| 	// iret
 | ||||
| 	// retf  <- int 21 4c jumps here to mimic a retf Cyber
 | ||||
| 
 | ||||
| 		callback[2].Install(DOS_25Handler,CB_RETF,"DOS Int 25"); | ||||
| 		callback[2].Install(DOS_25Handler,CB_RETF_STI,"DOS Int 25"); | ||||
| 		callback[2].Set_RealVec(0x25); | ||||
| 
 | ||||
| 		callback[3].Install(DOS_26Handler,CB_RETF,"DOS Int 26"); | ||||
| 		callback[3].Install(DOS_26Handler,CB_RETF_STI,"DOS Int 26"); | ||||
| 		callback[3].Set_RealVec(0x26); | ||||
| 
 | ||||
| 		callback[4].Install(DOS_27Handler,CB_IRET,"DOS Int 27"); | ||||
|  |  | |||
|  | @ -36,8 +36,8 @@ | |||
| static Bitu call_int33,call_int74,int74_ret_callback,call_mouse_bd; | ||||
| static Bit16u ps2cbseg,ps2cbofs; | ||||
| static bool useps2callback,ps2callbackinit; | ||||
| static Bitu call_ps2; | ||||
| static RealPt ps2_callback; | ||||
| static Bitu call_ps2,call_uir; | ||||
| static RealPt ps2_callback,uir_callback; | ||||
| static Bit16s oldmouseX, oldmouseY; | ||||
| // forward
 | ||||
| void WriteMouseIntVector(void); | ||||
|  | @ -698,6 +698,15 @@ static void Mouse_Reset(void) { | |||
| 	mouse.mickey_x = 0; | ||||
| 	mouse.mickey_y = 0; | ||||
| 
 | ||||
| 	for (Bit16u but=0; but<MOUSE_BUTTONS; but++) { | ||||
| 		mouse.times_pressed[but] = 0; | ||||
| 		mouse.times_released[but] = 0; | ||||
| 		mouse.last_pressed_x[but] = 0; | ||||
| 		mouse.last_pressed_y[but] = 0; | ||||
| 		mouse.last_released_x[but] = 0; | ||||
| 		mouse.last_released_y[but] = 0; | ||||
| 	} | ||||
| 
 | ||||
| 	// Dont set max coordinates here. it is done by SetResolution!
 | ||||
| 	mouse.x = static_cast<float>((mouse.max_x + 1)/ 2); | ||||
| 	mouse.y = static_cast<float>((mouse.max_y + 1)/ 2); | ||||
|  | @ -1030,7 +1039,7 @@ static Bitu MOUSE_BD_Handler(void) { | |||
| } | ||||
| 
 | ||||
| static Bitu INT74_Handler(void) { | ||||
| 	if (mouse.events>0) { | ||||
| 	if (mouse.events>0 && !mouse.in_UIR) { | ||||
| 		mouse.events--; | ||||
| 		/* Check for an active Interrupt Handler that will get called */ | ||||
| 		if (mouse.sub_mask & mouse.event_queue[mouse.events].type) { | ||||
|  | @ -1041,10 +1050,11 @@ static Bitu INT74_Handler(void) { | |||
| 			reg_si=static_cast<Bit16s>(mouse.mickey_x); | ||||
| 			reg_di=static_cast<Bit16s>(mouse.mickey_y); | ||||
| 			CPU_Push16(RealSeg(CALLBACK_RealPointer(int74_ret_callback))); | ||||
| 			CPU_Push16(RealOff(CALLBACK_RealPointer(int74_ret_callback))); | ||||
| 			SegSet16(cs, mouse.sub_seg); | ||||
| 			reg_ip = mouse.sub_ofs; | ||||
| 			if(mouse.in_UIR) LOG(LOG_MOUSE,LOG_ERROR)("Already in UIR!"); | ||||
| 			CPU_Push16(RealOff(CALLBACK_RealPointer(int74_ret_callback))+7); | ||||
| 			CPU_Push16(RealSeg(uir_callback)); | ||||
| 			CPU_Push16(RealOff(uir_callback)); | ||||
| 			CPU_Push16(mouse.sub_seg); | ||||
| 			CPU_Push16(mouse.sub_ofs); | ||||
| 			mouse.in_UIR = true; | ||||
| 			//LOG(LOG_MOUSE,LOG_ERROR)("INT 74 %X",mouse.event_queue[mouse.events].type );
 | ||||
| 		} else if (useps2callback) { | ||||
|  | @ -1064,8 +1074,7 @@ static Bitu INT74_Handler(void) { | |||
| 	return CBRET_NONE; | ||||
| } | ||||
| 
 | ||||
| Bitu MOUSE_UserInt_CB_Handler(void) { | ||||
| 	mouse.in_UIR = false; | ||||
| Bitu INT74_Ret_Handler(void) { | ||||
| 	if (mouse.events) { | ||||
| 		if (!mouse.timer_in_progress) { | ||||
| 			mouse.timer_in_progress = true; | ||||
|  | @ -1075,6 +1084,11 @@ Bitu MOUSE_UserInt_CB_Handler(void) { | |||
| 	return CBRET_NONE; | ||||
| } | ||||
| 
 | ||||
| Bitu UIR_Handler(void) { | ||||
| 	mouse.in_UIR = false; | ||||
| 	return CBRET_NONE; | ||||
| } | ||||
| 
 | ||||
| void MOUSE_Init(Section* /*sec*/) { | ||||
| 	// Callback for mouse interrupt 0x33
 | ||||
| 	call_int33=CALLBACK_Allocate(); | ||||
|  | @ -1100,22 +1114,29 @@ void MOUSE_Init(Section* /*sec*/) { | |||
| 	call_int74=CALLBACK_Allocate(); | ||||
| 	CALLBACK_Setup(call_int74,&INT74_Handler,CB_IRQ12,"int 74"); | ||||
| 	// pseudocode for CB_IRQ12:
 | ||||
| 	//	sti
 | ||||
| 	//	push ds
 | ||||
| 	//	push es
 | ||||
| 	//	pushad
 | ||||
| 	//	sti
 | ||||
| 	//	callback INT74_Handler
 | ||||
| 	//		doesn't return here, but rather to CB_IRQ12_RET
 | ||||
| 	//		(ps2 callback/user callback inbetween if requested)
 | ||||
| 	//		ps2 or user callback if requested
 | ||||
| 	//		otherwise jumps to CB_IRQ12_RET
 | ||||
| 	//	push ax
 | ||||
| 	//	mov al, 0x20
 | ||||
| 	//	out 0xa0, al
 | ||||
| 	//	out 0x20, al
 | ||||
| 	//	pop	ax
 | ||||
| 	//	cld
 | ||||
| 	//	retf
 | ||||
| 
 | ||||
| 	int74_ret_callback=CALLBACK_Allocate(); | ||||
| 	CALLBACK_Setup(int74_ret_callback,&MOUSE_UserInt_CB_Handler,CB_IRQ12_RET,"int 74 ret"); | ||||
| 	CALLBACK_Setup(int74_ret_callback,&INT74_Ret_Handler,CB_IRQ12_RET,"int 74 ret"); | ||||
| 	// pseudocode for CB_IRQ12_RET:
 | ||||
| 	//	callback MOUSE_UserInt_CB_Handler
 | ||||
| 	//	cli
 | ||||
| 	//	mov al, 0x20
 | ||||
| 	//	out 0xa0, al
 | ||||
| 	//	out 0x20, al
 | ||||
| 	//	callback INT74_Ret_Handler
 | ||||
| 	//	popad
 | ||||
| 	//	pop es
 | ||||
| 	//	pop ds
 | ||||
|  | @ -1130,6 +1151,11 @@ void MOUSE_Init(Section* /*sec*/) { | |||
| 	CALLBACK_Setup(call_ps2,&PS2_Handler,CB_RETF,"ps2 bios callback"); | ||||
| 	ps2_callback=CALLBACK_RealPointer(call_ps2); | ||||
| 
 | ||||
| 	// Callback for mouse user routine return
 | ||||
| 	call_uir=CALLBACK_Allocate(); | ||||
| 	CALLBACK_Setup(call_uir,&UIR_Handler,CB_RETF_CLI,"mouse uir ret"); | ||||
| 	uir_callback=CALLBACK_RealPointer(call_uir); | ||||
| 
 | ||||
| 	memset(&mouse,0,sizeof(mouse)); | ||||
| 	mouse.hidden = 1; //Hide mouse on startup
 | ||||
| 	mouse.timer_in_progress = false; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue