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
Reference in a new issue