summaryrefslogtreecommitdiffstats
path: root/board/MAI/bios_emulator/scitech/src/pm/smx/event.c
diff options
context:
space:
mode:
Diffstat (limited to 'board/MAI/bios_emulator/scitech/src/pm/smx/event.c')
-rw-r--r--board/MAI/bios_emulator/scitech/src/pm/smx/event.c368
1 files changed, 368 insertions, 0 deletions
diff --git a/board/MAI/bios_emulator/scitech/src/pm/smx/event.c b/board/MAI/bios_emulator/scitech/src/pm/smx/event.c
new file mode 100644
index 0000000000..fc13bbbe42
--- /dev/null
+++ b/board/MAI/bios_emulator/scitech/src/pm/smx/event.c
@@ -0,0 +1,368 @@
+/****************************************************************************
+*
+* SciTech OS Portability Manager Library
+*
+* ========================================================================
+*
+* The contents of this file are subject to the SciTech MGL Public
+* License Version 1.0 (the "License"); you may not use this file
+* except in compliance with the License. You may obtain a copy of
+* the License at http://www.scitechsoft.com/mgl-license.txt
+*
+* Software distributed under the License is distributed on an
+* "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+* implied. See the License for the specific language governing
+* rights and limitations under the License.
+*
+* The Original Code is Copyright (C) 1991-1998 SciTech Software, Inc.
+*
+* The Initial Developer of the Original Code is SciTech Software, Inc.
+* All Rights Reserved.
+*
+* ========================================================================
+*
+* Language: ANSI C
+* Environment: 32-bit SMX embedded systems development
+*
+* Description: 32-bit SMX implementation for the SciTech cross platform
+* event library.
+*
+****************************************************************************/
+
+#include "smx/ps2mouse.h"
+
+/*--------------------------- Global variables ----------------------------*/
+
+ibool _VARAPI _EVT_useEvents = true; /* True to use event handling */
+ibool _VARAPI _EVT_installed = 0; /* Event handers installed? */
+uchar _VARAPI *_EVT_biosPtr = NULL; /* Pointer to the BIOS data area */
+static ibool haveMouse = false; /* True if we have a mouse */
+
+/*---------------------------- Implementation -----------------------------*/
+
+/* External assembler functions */
+
+void EVTAPI _EVT_pollJoystick(void);
+uint EVTAPI _EVT_disableInt(void);
+uint EVTAPI _EVT_restoreInt(uint flags);
+void EVTAPI _EVT_codeStart(void);
+void EVTAPI _EVT_codeEnd(void);
+void EVTAPI _EVT_cCodeStart(void);
+void EVTAPI _EVT_cCodeEnd(void);
+int EVTAPI _EVT_getKeyCode(void);
+int EVTAPI EVT_rdinx(int port,int index);
+void EVTAPI EVT_wrinx(int port,int index,int value);
+
+/****************************************************************************
+REMARKS:
+Do nothing for DOS, because we are fully interrupt driven.
+****************************************************************************/
+#define _EVT_pumpMessages()
+
+/****************************************************************************
+REMARKS:
+This function is used to return the number of ticks since system
+startup in milliseconds. This should be the same value that is placed into
+the time stamp fields of events, and is used to implement auto mouse down
+events.
+****************************************************************************/
+ulong _EVT_getTicks(void)
+{
+ return (ulong)PM_getLong(_EVT_biosPtr+0x6C) * 55UL;
+}
+
+/****************************************************************************
+REMARKS:
+Include generic raw scancode keyboard module.
+****************************************************************************/
+#include "common/keyboard.c"
+
+/****************************************************************************
+REMARKS:
+Determines if we have a mouse attached and functioning.
+****************************************************************************/
+static ibool detectMouse(void)
+{
+ return(ps2Query());
+}
+
+/****************************************************************************
+PARAMETERS:
+what - Event code
+message - Event message
+x,y - Mouse position at time of event
+but_stat - Mouse button status at time of event
+
+REMARKS:
+Adds a new mouse event to the event queue. This routine is called from within
+the mouse interrupt subroutine, so it must be efficient.
+
+NOTE: Interrupts MUST be OFF while this routine is called to ensure we have
+ mutually exclusive access to our internal data structures for
+ interrupt driven systems (like under DOS).
+****************************************************************************/
+static void addMouseEvent(
+ uint what,
+ uint message,
+ int x,
+ int y,
+ int mickeyX,
+ int mickeyY,
+ uint but_stat)
+{
+ event_t evt;
+
+ if (EVT.count < EVENTQSIZE) {
+ /* Save information in event record. */
+ evt.when = _EVT_getTicks();
+ evt.what = what;
+ evt.message = message;
+ evt.modifiers = but_stat;
+ evt.where_x = x; /* Save mouse event position */
+ evt.where_y = y;
+ evt.relative_x = mickeyX;
+ evt.relative_y = mickeyY;
+ evt.modifiers |= EVT.keyModifiers;
+ addEvent(&evt); /* Add to tail of event queue */
+ }
+}
+
+/****************************************************************************
+PARAMETERS:
+mask - Event mask
+butstate - Button state
+x - Mouse x coordinate
+y - Mouse y coordinate
+
+REMARKS:
+Mouse event handling routine. This gets called when a mouse event occurs,
+and we call the addMouseEvent() routine to add the appropriate mouse event
+to the event queue.
+
+Note: Interrupts are ON when this routine is called by the mouse driver code.
+//AM: NOTE: This function has not actually been ported from DOS yet and should not
+//AM: be installed until it is.
+****************************************************************************/
+static void EVTAPI mouseISR(
+ uint mask,
+ uint butstate,
+ int x,
+ int y,
+ int mickeyX,
+ int mickeyY)
+{
+ RMREGS regs;
+ uint ps;
+
+ if (mask & 1) {
+ /* Save the current mouse coordinates */
+ EVT.mx = x; EVT.my = y;
+
+ /* If the last event was a movement event, then modify the last
+ * event rather than post a new one, so that the queue will not
+ * become saturated. Before we modify the data structures, we
+ * MUST ensure that interrupts are off.
+ */
+ ps = _EVT_disableInt();
+ if (EVT.oldMove != -1) {
+ EVT.evtq[EVT.oldMove].where_x = x; /* Modify existing one */
+ EVT.evtq[EVT.oldMove].where_y = y;
+ EVT.evtq[EVT.oldMove].relative_x += mickeyX;
+ EVT.evtq[EVT.oldMove].relative_y += mickeyY;
+ }
+ else {
+ EVT.oldMove = EVT.freeHead; /* Save id of this move event */
+ addMouseEvent(EVT_MOUSEMOVE,0,x,y,mickeyX,mickeyY,butstate);
+ }
+ _EVT_restoreInt(ps);
+ }
+ if (mask & 0x2A) {
+ ps = _EVT_disableInt();
+ addMouseEvent(EVT_MOUSEDOWN,mask >> 1,x,y,0,0,butstate);
+ EVT.oldMove = -1;
+ _EVT_restoreInt(ps);
+ }
+ if (mask & 0x54) {
+ ps = _EVT_disableInt();
+ addMouseEvent(EVT_MOUSEUP,mask >> 2,x,y,0,0,butstate);
+ EVT.oldMove = -1;
+ _EVT_restoreInt(ps);
+ }
+ EVT.oldKey = -1;
+}
+
+/****************************************************************************
+REMARKS:
+Keyboard interrupt handler function.
+
+NOTE: Interrupts are OFF when this routine is called by the keyboard ISR,
+ and we leave them OFF the entire time. This has been modified to work
+ in conjunction with smx keyboard handler.
+****************************************************************************/
+static void EVTAPI keyboardISR(void)
+{
+ PM_chainPrevKey();
+ processRawScanCode(PM_inpb(0x60));
+ PM_outpb(0x20,0x20);
+}
+
+/****************************************************************************
+REMARKS:
+Safely abort the event module upon catching a fatal error.
+****************************************************************************/
+void _EVT_abort()
+{
+ EVT_exit();
+ PM_fatalError("Unhandled exception!");
+}
+
+/****************************************************************************
+PARAMETERS:
+mouseMove - Callback function to call wheneve the mouse needs to be moved
+
+REMARKS:
+Initiliase the event handling module. Here we install our mouse handling ISR
+to be called whenever any button's are pressed or released. We also build
+the free list of events in the event queue.
+
+We use handler number 2 of the mouse libraries interrupt handlers for our
+event handling routines.
+****************************************************************************/
+void EVTAPI EVT_init(
+ _EVT_mouseMoveHandler mouseMove)
+{
+ int i;
+
+ EVT.mouseMove = mouseMove;
+ _EVT_biosPtr = PM_getBIOSPointer();
+ EVT_resume();
+}
+
+/****************************************************************************
+REMARKS:
+Initiailises the internal event handling modules. The EVT_suspend function
+can be called to suspend event handling (such as when shelling out to DOS),
+and this function can be used to resume it again later.
+****************************************************************************/
+void EVTAPI EVT_resume(void)
+{
+ static int locked = 0;
+ int stat;
+ uchar mods;
+ PM_lockHandle lh;
+
+ if (_EVT_useEvents) {
+ /* Initialise the event queue and enable our interrupt handlers */
+ initEventQueue();
+ PM_setKeyHandler(keyboardISR);
+ if ((haveMouse = detectMouse()) != 0)
+ PM_setMouseHandler(0xFFFF,mouseISR);
+
+ /* Read the keyboard modifier flags from the BIOS to get the
+ * correct initialisation state. The only state we care about is
+ * the correct toggle state flags such as SCROLLLOCK, NUMLOCK and
+ * CAPSLOCK.
+ */
+ EVT.keyModifiers = 0;
+ mods = PM_getByte(_EVT_biosPtr+0x17);
+ if (mods & 0x10)
+ EVT.keyModifiers |= EVT_SCROLLLOCK;
+ if (mods & 0x20)
+ EVT.keyModifiers |= EVT_NUMLOCK;
+ if (mods & 0x40)
+ EVT.keyModifiers |= EVT_CAPSLOCK;
+
+ /* Lock all of the code and data used by our protected mode interrupt
+ * handling routines, so that it will continue to work correctly
+ * under real mode.
+ */
+ if (!locked) {
+ /* It is difficult to ensure that we lock our global data, so we
+ * do this by taking the address of a variable locking all data
+ * 2Kb on either side. This should properly cover the global data
+ * used by the module (the other alternative is to declare the
+ * variables in assembler, in which case we know it will be
+ * correct).
+ */
+ stat = !PM_lockDataPages(&EVT,sizeof(EVT),&lh);
+ stat |= !PM_lockDataPages(&_EVT_biosPtr,sizeof(_EVT_biosPtr),&lh);
+ stat |= !PM_lockCodePages((__codePtr)_EVT_cCodeStart,(int)_EVT_cCodeEnd-(int)_EVT_cCodeStart,&lh);
+ stat |= !PM_lockCodePages((__codePtr)_EVT_codeStart,(int)_EVT_codeEnd-(int)_EVT_codeStart,&lh);
+ if (stat) {
+ PM_fatalError("Page locking services failed - interrupt handling not safe!");
+ exit(1);
+ }
+ locked = 1;
+ }
+
+ _EVT_installed = true;
+ }
+}
+
+/****************************************************************************
+REMARKS
+Changes the range of coordinates returned by the mouse functions to the
+specified range of values. This is used when changing between graphics
+modes set the range of mouse coordinates for the new display mode.
+****************************************************************************/
+void EVTAPI EVT_setMouseRange(
+ int xRes,
+ int yRes)
+{
+ if (haveMouse) {
+ ps2MouseStop();
+ ps2MouseStart( 0, xRes, 0, yRes, -1, -1, -1);
+ }
+}
+
+/****************************************************************************
+REMARKS
+Modifes the mouse coordinates as necessary if scaling to OS coordinates,
+and sets the OS mouse cursor position.
+****************************************************************************/
+void _EVT_setMousePos(
+ int *x,
+ int *y)
+{
+ if (haveMouse)
+ ps2MouseMove(*x, *y);
+}
+
+/****************************************************************************
+REMARKS
+Suspends all of our event handling operations. This is also used to
+de-install the event handling code.
+****************************************************************************/
+void EVTAPI EVT_suspend(void)
+{
+ uchar mods;
+
+ if (_EVT_installed) {
+ PM_restoreKeyHandler();
+ if (haveMouse)
+ PM_restoreMouseHandler();
+
+ /* Set the keyboard modifier flags in the BIOS to our values */
+ EVT_allowLEDS(true);
+ mods = PM_getByte(_EVT_biosPtr+0x17) & ~0x70;
+ if (EVT.keyModifiers & EVT_SCROLLLOCK)
+ mods |= 0x10;
+ if (EVT.keyModifiers & EVT_NUMLOCK)
+ mods |= 0x20;
+ if (EVT.keyModifiers & EVT_CAPSLOCK)
+ mods |= 0x40;
+ PM_setByte(_EVT_biosPtr+0x17,mods);
+
+ /* Flag that we are no longer installed */
+ _EVT_installed = false;
+ }
+}
+
+/****************************************************************************
+REMARKS
+Exits the event module for program terminatation.
+****************************************************************************/
+void EVTAPI EVT_exit(void)
+{
+ EVT_suspend();
+}
OpenPOWER on IntegriCloud