void Mouse_ChangePS2Callback(Bit16u pseg, Bit16u pofs) { if ((pseg==0) && (pofs==0)) { ps2callbackinit = false; Mouse_AutoLock(false); } else { ps2callbackinit = true; ps2cbseg = pseg; ps2cbofs = pofs; } Mouse_AutoLock(ps2callbackinit); }
bool Mouse_SetPS2State(bool use) { if (use && (!ps2callbackinit)) { useps2callback = false; PIC_SetIRQMask(MOUSE_IRQ,true); return false; } useps2callback = use; Mouse_AutoLock(useps2callback); PIC_SetIRQMask(MOUSE_IRQ,!useps2callback); return true; }
static Bitu INT33_Handler(void) { // LOG(LOG_MOUSE,LOG_NORMAL)("MOUSE: %04X %X %X %d %d",reg_ax,reg_bx,reg_cx,POS_X,POS_Y); switch (reg_ax) { case 0x00: /* Reset Driver and Read Status */ Mouse_ResetHardware(); /* fallthrough */ case 0x21: /* Software Reset */ reg_ax=0xffff; reg_bx=MOUSE_BUTTONS; Mouse_Reset(); Mouse_AutoLock(true); break; case 0x01: /* Show Mouse */ if(mouse.hidden) mouse.hidden--; Mouse_AutoLock(true); DrawCursor(); break; case 0x02: /* Hide Mouse */ { if (CurMode->type!=M_TEXT) RestoreCursorBackground(); else RestoreCursorBackgroundText(); mouse.hidden++; } break; case 0x03: /* Return position and Button Status */ reg_bx=mouse.buttons; reg_cx=POS_X; reg_dx=POS_Y; break; case 0x04: /* Position Mouse */ /* If position isn't different from current position * don't change it then. (as position is rounded so numbers get * lost when the rounded number is set) (arena/simulation Wolf) */ if ((Bit16s)reg_cx >= mouse.max_x) mouse.x = static_cast<float>(mouse.max_x); else if (mouse.min_x >= (Bit16s)reg_cx) mouse.x = static_cast<float>(mouse.min_x); else if ((Bit16s)reg_cx != POS_X) mouse.x = static_cast<float>(reg_cx); if ((Bit16s)reg_dx >= mouse.max_y) mouse.y = static_cast<float>(mouse.max_y); else if (mouse.min_y >= (Bit16s)reg_dx) mouse.y = static_cast<float>(mouse.min_y); else if ((Bit16s)reg_dx != POS_Y) mouse.y = static_cast<float>(reg_dx); DrawCursor(); break; case 0x05: /* Return Button Press Data */ { Bit16u but=reg_bx; reg_ax=mouse.buttons; if (but>=MOUSE_BUTTONS) but = MOUSE_BUTTONS - 1; reg_cx=mouse.last_pressed_x[but]; reg_dx=mouse.last_pressed_y[but]; reg_bx=mouse.times_pressed[but]; mouse.times_pressed[but]=0; break; } case 0x06: /* Return Button Release Data */ { Bit16u but=reg_bx; reg_ax=mouse.buttons; if (but>=MOUSE_BUTTONS) but = MOUSE_BUTTONS - 1; reg_cx=mouse.last_released_x[but]; reg_dx=mouse.last_released_y[but]; reg_bx=mouse.times_released[but]; mouse.times_released[but]=0; break; } case 0x07: /* Define horizontal cursor range */ { //lemmings set 1-640 and wants that. iron seeds set 0-640 but doesn't like 640 //Iron seed works if newvideo mode with mode 13 sets 0-639 //Larry 6 actually wants newvideo mode with mode 13 to set it to 0-319 Bit16s max,min; if ((Bit16s)reg_cx<(Bit16s)reg_dx) { min=(Bit16s)reg_cx;max=(Bit16s)reg_dx;} else { min=(Bit16s)reg_dx;max=(Bit16s)reg_cx;} mouse.min_x=min; mouse.max_x=max; /* Battlechess wants this */ if(mouse.x > mouse.max_x) mouse.x = mouse.max_x; if(mouse.x < mouse.min_x) mouse.x = mouse.min_x; /* Or alternatively this: mouse.x = (mouse.max_x - mouse.min_x + 1)/2;*/ LOG(LOG_MOUSE,LOG_NORMAL)("Define Hortizontal range min:%d max:%d",min,max); } break; case 0x08: /* Define vertical cursor range */ { // not sure what to take instead of the CurMode (see case 0x07 as well) // especially the cases where sheight= 400 and we set it with the mouse_reset to 200 //disabled it at the moment. Seems to break syndicate who want 400 in mode 13 Bit16s max,min; if ((Bit16s)reg_cx<(Bit16s)reg_dx) { min=(Bit16s)reg_cx;max=(Bit16s)reg_dx;} else { min=(Bit16s)reg_dx;max=(Bit16s)reg_cx;} mouse.min_y=min; mouse.max_y=max; /* Battlechess wants this */ if(mouse.y > mouse.max_y) mouse.y = mouse.max_y; if(mouse.y < mouse.min_y) mouse.y = mouse.min_y; /* Or alternatively this: mouse.y = (mouse.max_y - mouse.min_y + 1)/2;*/ LOG(LOG_MOUSE,LOG_NORMAL)("Define Vertical range min:%d max:%d",min,max); } break; case 0x09: /* Define GFX Cursor */ { PhysPt src = SegPhys(es)+reg_dx; MEM_BlockRead(src ,userdefScreenMask,CURSORY*2); MEM_BlockRead(src+CURSORY*2,userdefCursorMask,CURSORY*2); mouse.screenMask = userdefScreenMask; mouse.cursorMask = userdefCursorMask; mouse.hotx = reg_bx; mouse.hoty = reg_cx; mouse.cursorType = 2; DrawCursor(); } break; case 0x0a: /* Define Text Cursor */ mouse.cursorType = reg_bx; mouse.textAndMask = reg_cx; mouse.textXorMask = reg_dx; break; case 0x0b: /* Read Motion Data */ reg_cx=(Bit16s)(mouse.mickey_x*mouse.mickeysPerPixel_x); reg_dx=(Bit16s)(mouse.mickey_y*mouse.mickeysPerPixel_y); mouse.mickey_x=0; mouse.mickey_y=0; break; case 0x0c: /* Define interrupt subroutine parameters */ mouse.sub_mask=reg_cx; mouse.sub_seg=SegValue(es); mouse.sub_ofs=reg_dx; Mouse_AutoLock(true); //Some games don't seem to reset the mouse before using break; case 0x0f: /* Define mickey/pixel rate */ Mouse_SetMickeyPixelRate(reg_cx,reg_dx); break; case 0x10: /* Define screen region for updating */ mouse.updateRegion_x[0]=reg_cx; mouse.updateRegion_y[0]=reg_dx; mouse.updateRegion_x[1]=reg_si; mouse.updateRegion_y[1]=reg_di; break; case 0x11: /* Get number of buttons */ reg_ax=0xffff; reg_bx=MOUSE_BUTTONS; break; case 0x13: /* Set double-speed threshold */ mouse.doubleSpeedThreshold=(reg_bx ? reg_bx : 64); break; case 0x14: /* Exchange event-handler */ { Bit16u oldSeg = mouse.sub_seg; Bit16u oldOfs = mouse.sub_ofs; Bit16u oldMask= mouse.sub_mask; // Set new values mouse.sub_mask= reg_cx; mouse.sub_seg = SegValue(es); mouse.sub_ofs = reg_dx; // Return old values reg_cx = oldMask; reg_dx = oldOfs; SegSet16(es,oldSeg); } break; case 0x15: /* Get Driver storage space requirements */ reg_bx = sizeof(mouse); break; case 0x16: /* Save driver state */ { LOG(LOG_MOUSE,LOG_WARN)("Saving driver state..."); PhysPt dest = SegPhys(es)+reg_dx; MEM_BlockWrite(dest, &mouse, sizeof(mouse)); } break; case 0x17: /* load driver state */ { LOG(LOG_MOUSE,LOG_WARN)("Loading driver state..."); PhysPt src = SegPhys(es)+reg_dx; MEM_BlockRead(src, &mouse, sizeof(mouse)); } break; case 0x1a: /* Set mouse sensitivity */ // ToDo : double mouse speed value Mouse_SetSensitivity(reg_bx,reg_cx,reg_dx); LOG(LOG_MOUSE,LOG_WARN)("Set sensitivity used with %d %d (%d)",reg_bx,reg_cx,reg_dx); break; case 0x1b: /* Get mouse sensitivity */ reg_bx = mouse.senv_x_val; reg_cx = mouse.senv_y_val; reg_dx = mouse.dspeed_val; LOG(LOG_MOUSE,LOG_WARN)("Get sensitivity %d %d",reg_bx,reg_cx); break; case 0x1c: /* Set interrupt rate */ /* Can't really set a rate this is host determined */ break; case 0x1d: /* Set display page number */ mouse.page=reg_bl; break; case 0x1e: /* Get display page number */ reg_bx=mouse.page; break; case 0x1f: /* Disable Mousedriver */ /* ES:BX old mouse driver Zero at the moment TODO */ reg_bx=0; SegSet16(es,0); mouse.enabled=false; /* Just for reporting not doing a thing with it */ mouse.oldhidden=mouse.hidden; mouse.hidden=1; break; case 0x20: /* Enable Mousedriver */ mouse.enabled=true; mouse.hidden=mouse.oldhidden; break; case 0x22: /* Set language for messages */ /* * Values for mouse driver language: * * 00h English * 01h French * 02h Dutch * 03h German * 04h Swedish * 05h Finnish * 06h Spanish * 07h Portugese * 08h Italian * */ mouse.language=reg_bx; break; case 0x23: /* Get language for messages */ reg_bx=mouse.language; break; case 0x24: /* Get Software version and mouse type */ reg_bx=0x805; //Version 8.05 woohoo reg_ch=0x04; /* PS/2 type */ reg_cl=0; /* PS/2 (unused) */ break; case 0x26: /* Get Maximum virtual coordinates */ reg_bx=(mouse.enabled ? 0x0000 : 0xffff); reg_cx=(Bit16u)mouse.max_x; reg_dx=(Bit16u)mouse.max_y; break; case 0x31: /* Get Current Minimum/Maximum virtual coordinates */ reg_ax=(Bit16u)mouse.min_x; reg_bx=(Bit16u)mouse.min_y; reg_cx=(Bit16u)mouse.max_x; reg_dx=(Bit16u)mouse.max_y; break; default: LOG(LOG_MOUSE,LOG_ERROR)("Mouse Function %04X not implemented!",reg_ax); break; } return CBRET_NONE; }
void KEYBOARD_AUX_Write(Bitu val) { if (keyb.ps2mouse.type == MOUSE_NONE) return; if (keyb.ps2mouse.mode == MM_WRAP) { if (val != 0xFF && val != 0xEC) { KEYBOARD_AddBuffer(AUX|val); return; } } switch (keyb.aux_command) { case ACMD_NONE: switch (val) { case 0xff: /* reset */ LOG(LOG_KEYBOARD,LOG_NORMAL)("AUX reset"); KEYBOARD_AddBuffer(AUX|0xfa); /* ack */ KEYBOARD_AddBuffer(AUX|0xaa); /* reset */ KEYBOARD_AddBuffer(AUX|0x00); /* i am mouse */ Mouse_AutoLock(false); AUX_Reset(); break; case 0xf6: /* set defaults */ KEYBOARD_AddBuffer(AUX|0xfa); /* ack */ AUX_Reset(); break; case 0xf5: /* disable data reporting */ KEYBOARD_AddBuffer(AUX|0xfa); /* ack */ keyb.ps2mouse.reporting = false; break; case 0xf4: /* enable data reporting */ KEYBOARD_AddBuffer(AUX|0xfa); /* ack */ keyb.ps2mouse.reporting = true; Mouse_AutoLock(true); break; case 0xf3: /* set sample rate */ KEYBOARD_AddBuffer(AUX|0xfa); /* ack */ keyb.aux_command = ACMD_SET_RATE; break; case 0xf2: /* get device ID */ KEYBOARD_AddBuffer(AUX|0xfa); /* ack */ /* and then the ID */ if (keyb.ps2mouse.intellimouse_btn45) KEYBOARD_AddBuffer(AUX|0x04); else if (keyb.ps2mouse.intellimouse_mode) KEYBOARD_AddBuffer(AUX|0x03); else KEYBOARD_AddBuffer(AUX|0x00); break; case 0xf0: /* set remote mode */ KEYBOARD_AddBuffer(AUX|0xfa); /* ack */ keyb.ps2mouse.mode = MM_REMOTE; break; case 0xee: /* set wrap mode */ KEYBOARD_AddBuffer(AUX|0xfa); /* ack */ keyb.ps2mouse.mode = MM_WRAP; break; case 0xec: /* reset wrap mode */ KEYBOARD_AddBuffer(AUX|0xfa); /* ack */ keyb.ps2mouse.mode = MM_REMOTE; break; case 0xeb: /* read data */ KEYBOARD_AddBuffer(AUX|0xfa); /* ack */ KEYBOARD_AUX_Event(0,0, (keyb.ps2mouse.m << 2)| (keyb.ps2mouse.r << 1)| (keyb.ps2mouse.l << 0), 0); break; case 0xea: /* set stream mode */ KEYBOARD_AddBuffer(AUX|0xfa); /* ack */ keyb.ps2mouse.mode = MM_STREAM; break; case 0xe9: /* status request */ KEYBOARD_AddBuffer(AUX|0xfa); /* ack */ KEYBOARD_AddBuffer(AUX|KEYBOARD_AUX_DevStatus()); KEYBOARD_AddBuffer(AUX|keyb.ps2mouse.resolution); KEYBOARD_AddBuffer(AUX|keyb.ps2mouse.samplerate); break; case 0xe8: /* set resolution */ KEYBOARD_AddBuffer(AUX|0xfa); /* ack */ keyb.aux_command = ACMD_SET_RESOLUTION; break; case 0xe7: /* set scaling 2:1 */ KEYBOARD_AddBuffer(AUX|0xfa); /* ack */ keyb.ps2mouse.scale21 = true; LOG(LOG_KEYBOARD,LOG_NORMAL)("PS/2 mouse scaling 2:1"); break; case 0xe6: /* set scaling 1:1 */ KEYBOARD_AddBuffer(AUX|0xfa); /* ack */ keyb.ps2mouse.scale21 = false; LOG(LOG_KEYBOARD,LOG_NORMAL)("PS/2 mouse scaling 1:1"); break; } break; case ACMD_SET_RATE: KEYBOARD_AddBuffer(AUX|0xfa); /* ack */ memmove(keyb.ps2mouse.last_srate,keyb.ps2mouse.last_srate+1,2); keyb.ps2mouse.last_srate[2] = val; keyb.ps2mouse.samplerate = val; keyb.aux_command = ACMD_NONE; LOG(LOG_KEYBOARD,LOG_NORMAL)("PS/2 mouse sample rate set to %u",(int)val); if (keyb.ps2mouse.type >= MOUSE_INTELLIMOUSE) { if (keyb.ps2mouse.last_srate[0] == 200 && keyb.ps2mouse.last_srate[2] == 80) { if (keyb.ps2mouse.last_srate[1] == 100) { if (!keyb.ps2mouse.intellimouse_mode) { LOG(LOG_KEYBOARD,LOG_NORMAL)("Intellimouse mode enabled"); keyb.ps2mouse.intellimouse_mode=true; } } else if (keyb.ps2mouse.last_srate[1] == 200 && keyb.ps2mouse.type >= MOUSE_INTELLIMOUSE45) { if (!keyb.ps2mouse.intellimouse_btn45) { LOG(LOG_KEYBOARD,LOG_NORMAL)("Intellimouse 4/5-button mode enabled"); keyb.ps2mouse.intellimouse_btn45=true; } } } } break; case ACMD_SET_RESOLUTION: keyb.aux_command = ACMD_NONE; KEYBOARD_AddBuffer(AUX|0xfa); /* ack */ keyb.ps2mouse.resolution = val & 3; LOG(LOG_KEYBOARD,LOG_NORMAL)("PS/2 mouse resolution set to %u",(int)(1 << (val&3))); break; }; }