www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1994/09/29/01:22:31

Date: Wed, 28 Sep 94 23:11:59 EDT
From: dliu AT faraday-gw DOT njit DOT edu (Dong Liu)
To: djgpp AT sun DOT soe DOT clarkson DOT edu
Subject: [Q] _go32_dpmi_allocate_real_mode_callback_retf
Mailer: VM 5.32 (beta) for GNU Emacs 18.59.5

Hi, 

I have a question about the function
_go32_dpmi_allocate_real_mode_callback_retf (such a long name), what is
the restriction of the callback function, how large is the stack of that
function? I try to allocate a real mode callback then install the real
mode address as a mouse handler. If the callback function just modified
a static variable, it is ok. But if this function tried to do something
more compilcate (in my case, convert the value of CX to hex number then
directly write to ScreenPrimay), I got a seg violation at EIP=1 if I
moved my mouse for a while.

The program is taken from the turbvision mouse handling part. I have it
appeded here. Please tell me what I did wrong here? 

Thanks,  --dong

PS. are disable() and enable() necessary for the callback function?

---- tstmouse.cc -------
// mouse functions 

#include <dos.h>
#include <dpmi.h>
#include <string.h>
#include <pc.h>

typedef unsigned short ushort;
typedef unsigned char uchar;
enum Boolean { False, True };

struct TPoint
{
    ushort x,y;
};

struct MouseEventType
{
    uchar buttons;
    Boolean doubleClick;
    TPoint where;
};

class THWMouse
{

protected:

    THWMouse();
    THWMouse( const THWMouse& ) {};
    ~THWMouse();

    static void show();
    static void hide();

    static void setRange( ushort, ushort );
    static void getEvent( MouseEventType& );
    static void registerHandler( unsigned, void (*)(_go32_dpmi_registers *) );
    static Boolean present();

    static void suspend();
    static void resume();
    static void inhibit();

protected:

    static uchar buttonCount;

private:

    static Boolean handlerInstalled;
    static Boolean noMouse;
};

inline Boolean THWMouse::present()
{
    return Boolean( buttonCount != 0 );
}

inline void THWMouse::inhibit()
{
    noMouse = True;
}


 uchar THWMouse::buttonCount = 0;
 Boolean  THWMouse::handlerInstalled = False;
 Boolean  THWMouse:: noMouse= False; // !!! not used at all!?
static _go32_dpmi_registers mouse_handler_regs;
static _go32_dpmi_seginfo mouse_handler_seginfo;


THWMouse::THWMouse()
{
    resume();
}

void THWMouse::resume()
{
    _go32_dpmi_seginfo info;
    _go32_dpmi_get_real_mode_interrupt_vector(0x33, &info);
    if (info.rm_offset == 0 && info.rm_segment == 0)
	return;

    _go32_dpmi_registers regs;
    
    memset(&regs, 0, sizeof(regs));

    regs.x.ax=0;		// reset mouse
    _go32_dpmi_simulate_int(0x33, &regs);
    buttonCount = regs.x.bx;

    if (buttonCount==0x7FFF) return;
    if (buttonCount==0xffff) buttonCount=2;
    memset(&regs, 0, sizeof(regs));
    regs.x.ax=4; // set mouse position
    regs.x.cx=0;
    regs.x.dx=0;
    _go32_dpmi_simulate_int(0x33, &regs);
}

THWMouse::~THWMouse()
{
    suspend();
}

void THWMouse::suspend()
{
    if( present() == False )
        return;
    hide();
    if( handlerInstalled == True )
        {
        registerHandler( 0, 0 );
        handlerInstalled = False;
        }
    buttonCount = 0;
}


void THWMouse::show()
{
    _go32_dpmi_registers regs;
    memset(&regs, 0, sizeof regs);
    regs.x.ax=1; // Show cursor
    _go32_dpmi_simulate_int( 0x33, &regs );
}

void THWMouse::hide()
{
    _go32_dpmi_registers regs;
    memset(&regs, 0, sizeof regs);
    regs.x.ax=2; // Hide cursor
    _go32_dpmi_simulate_int( 0x33, &regs );
}

void THWMouse::setRange( ushort rx, ushort ry )
{
    if( buttonCount != 0 )
    {
	_go32_dpmi_registers regs;
	memset(&regs, 0, sizeof regs);
	regs.x.ax=7; 
	regs.x.cx=0;
	regs.x.dx=(rx<<3);
	_go32_dpmi_simulate_int( 0x33, &regs );

	memset(&regs, 0, sizeof regs);
	regs.x.ax=8; 
	regs.x.cx=0;
	regs.x.dx=(ry<<3);
	_go32_dpmi_simulate_int( 0x33, &regs );
    }
}

void THWMouse::getEvent( MouseEventType& me )
{
    _go32_dpmi_registers r;
    memset(&r, 0, sizeof r);
    r.x.ax=3;			// get state
    _go32_dpmi_simulate_int( 0x33, &r );
    me.buttons = r.h.bl;
    me.where.x = r.x.cx >> 3;
    me.where.y = r.x.dx >> 3;
    me.doubleClick = False;
}

void THWMouse::registerHandler
( unsigned mask, void (*func)(_go32_dpmi_registers *r) )
{

    if( !present() )
        return;
    if (func && (handlerInstalled != False)) // already register an
					    // handler
	return;

    _go32_dpmi_registers regs;
    if ( func == 0) {
	regs.x.ax = 12; // install handler
	regs.x.cx = mask;
	regs.x.dx = 0;
	regs.x.es  = 0;
	regs.x.ss = regs.x.sp = 0;
	_go32_dpmi_simulate_int(0x33, &regs );
	if (handlerInstalled == True) {
	    handlerInstalled = False;
	    _go32_dpmi_free_real_mode_callback(&mouse_handler_seginfo);
	}
	return;
    }
    mouse_handler_seginfo.pm_offset = (unsigned long)func;
    _go32_dpmi_allocate_real_mode_callback_retf(
	&mouse_handler_seginfo, &mouse_handler_regs);
    memset(&regs, 0, sizeof regs);
    regs.x.ax = 12; // install handler
    regs.x.cx = mask;
    regs.x.dx = mouse_handler_seginfo.rm_offset;
    regs.x.es   = mouse_handler_seginfo.rm_segment;
    _go32_dpmi_simulate_int(0x33, &regs);
    handlerInstalled = True;
}
class TMouse : public THWMouse
{

public:

    TMouse(){};
    ~TMouse(){};

    static void show();
    static void hide();

    static void setRange( ushort, ushort );

    static void getEvent( MouseEventType& );
    static void registerHandler( unsigned, void (*)(_go32_dpmi_registers *) );
    static Boolean present();

    static void suspend() { THWMouse::suspend(); }
    static void resume(); 

};

inline void TMouse::show()
{
    THWMouse::show();
}

inline void TMouse::resume()
{
  THWMouse::resume(); show();
};

inline void TMouse::hide()
{
    THWMouse::hide();
}

inline void TMouse::setRange( ushort rx, ushort ry )
{
    THWMouse::setRange( rx, ry );
}

inline void TMouse::getEvent( MouseEventType& me )
{
    THWMouse::getEvent( me );
}

#ifdef __GO32__
inline void TMouse::registerHandler
       ( unsigned mask, void (*func)(_go32_dpmi_registers *) )
#else
inline void TMouse::registerHandler( unsigned mask, void (*func)() )
#endif
{
    THWMouse::registerHandler( mask, func );
}

inline Boolean TMouse::present()
{
    return THWMouse::present();
}

// test
static char tmp[100];
static char *myitoa(unsigned int value, char *string, int radix)
{
  char *tp = tmp;
  int i;
  unsigned v;
  int sign;
  char *sp;

  sp = string;

  sign = (radix == 10 && value < 0);
  if (sign)
    v = -value;
  else
    v = (unsigned)value;
  while (v || tp == tmp)
  {
    i = v % radix;
    v = v / radix;
    if (i < 10)
      *tp++ = i+'0';
    else
      *tp++ = i + 'a' - 10;
  }
  if (sign)
    *sp++ = '-';
  while (tp > tmp)
    *sp++ = *--tp;
  *sp = 0;
  return string;
}

static void
ScreenPuts(int line, char *p)
{
    char *d = (char *)ScreenPrimary + 160*line;
    for(; *p; p++, d+= 2)
       *d = *p;
}
static char num[100];
void mouseProc(_go32_dpmi_registers *regs)
{
    disable();    
 //   ScreenPuts(0, "XXXX");
 //   return;
    myitoa(regs -> x.cx, num, 16);
    ScreenPuts(0,num);
    enable();
}
main()
{
    TMouse mouse;
    if(mouse.present()) {
	mouse.show();
	mouse.registerHandler(0xffff, mouseProc);
	while (getkey() != 0x1b)
	   ;
	mouse.hide();
    }
}

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019