Ejemplo n.º 1
0
/* _install_irq:
 *  Installs a hardware interrupt handler for the specified irq, allocating
 *  an asm wrapper function which will save registers and handle the stack
 *  switching. The C function should return zero to exit the interrupt with 
 *  an iret instruction, and non-zero to chain to the old handler.
 */
int _install_irq(int num, int (*handler)(void))
{
   __dpmi_paddr addr;
   int c;

   for (c=0; c<MAX_IRQS; c++) {
      if (_irq_handler[c].handler == NULL) {

	 addr.selector = _my_cs();

	 switch (c) {
	    case 0: addr.offset32 = (long)_irq_wrapper_0; break;
	    case 1: addr.offset32 = (long)_irq_wrapper_1; break;
	    case 2: addr.offset32 = (long)_irq_wrapper_2; break;
	    case 3: addr.offset32 = (long)_irq_wrapper_3; break;
	    case 4: addr.offset32 = (long)_irq_wrapper_4; break;
	    case 5: addr.offset32 = (long)_irq_wrapper_5; break;
	    case 6: addr.offset32 = (long)_irq_wrapper_6; break;
	    case 7: addr.offset32 = (long)_irq_wrapper_7; break;
	    default: return -1;
	 }

	 _irq_handler[c].handler = handler;
	 _irq_handler[c].number = num;

	 __dpmi_get_protected_mode_interrupt_vector(num, &_irq_handler[c].old_vector);
	 __dpmi_set_protected_mode_interrupt_vector(num, &addr);

	 return 0;
      }
   }

   return -1;
}
Ejemplo n.º 2
0
static void update_async()
{
    int time = tl_process_group(asyncgroup);
    if (time != -1) {
	struct itimerval t;
	t.it_interval.tv_sec = 0;
	t.it_interval.tv_usec = 0;
	t.it_value.tv_sec = time / 1000000;
	t.it_value.tv_usec = time % 1000000;
	if (!reghandler) {
#ifdef __DJGPP__
            _go32_dpmi_seginfo pmint;
            pmint.pm_selector=_my_cs();
	    pmint.pm_offset=&alarmhandler;
	    _go32_dpmi_chain_protected_mode_interrupt_vector(0x1c,&pmint);
#endif
	    signal(SIGALRM, alarmhandler), reghandler = 1;
	}
	setitimer(ITIMER_REAL, &t, &t);
	registered = 1;
    }
    else if (registered) {
	struct itimerval t;
	t.it_interval.tv_sec = 0;
	t.it_interval.tv_usec = 0;
	t.it_value.tv_sec = 0;
	t.it_value.tv_usec = 0;
	setitimer(ITIMER_REAL, &t, &t);
	registered = 0;
    }
}
Ejemplo n.º 3
0
/* go to background: TSR */
void
msdosBackground (void) {
  __djgpp_set_ctrl_c(0);
  saveState(&mainState);

  if (!setjmp(mainContext)) {
    __dpmi_regs regs;

    /* set a chained Protected Mode Timer IRQ handler */
    timerSeginfo.pm_selector = _my_cs();
    timerSeginfo.pm_offset = (unsigned long)&timerInterruptHandler;
    _go32_dpmi_get_protected_mode_interrupt_vector(TIMER_INTERRUPT, &origTimerSeginfo);
    _go32_dpmi_chain_protected_mode_interrupt_vector(TIMER_INTERRUPT, &timerSeginfo);

    /* set a real mode DOS Idle handler which calls back our Idle handler */
    idleSeginfo.pm_selector = _my_cs();
    idleSeginfo.pm_offset = (unsigned long)&idleInterruptHandler;
    memset(&idleRegisters, 0, sizeof(idleRegisters));
    _go32_dpmi_get_real_mode_interrupt_vector(IDLE_INTERRUPT, &origIdleSeginfo);
    _go32_dpmi_allocate_real_mode_callback_iret(&idleSeginfo, &idleRegisters);
    _go32_dpmi_set_real_mode_interrupt_vector(IDLE_INTERRUPT, &idleSeginfo);

    /* Get InDos and Critical flags addresses */
    regs.h.ah = 0X34;
    __dpmi_int(DOS_INTERRUPT, &regs);
    inDosFlagPointer = msdosMakeAddress(regs.x.es, regs.x.bx);

    regs.x.ax = 0X5D06;
    __dpmi_int(DOS_INTERRUPT, &regs);
    criticalOffset = msdosMakeAddress(regs.x.ds, regs.x.si);

    /* We are ready */
    isBackgrounded = 1;

    regs.x.ax = 0X3100;
    msdosBreakAddress(0X100/*psp*/ + _go32_info_block.size_of_transfer_buffer, 0,
                      &regs.x.dx, NULL);
    __dpmi_int(DOS_INTERRUPT, &regs);

    /* shouldn't be reached */
    logMessage(LOG_ERR, "TSR installation failed");
    isBackgrounded = 0;
  }

  saveState(&interruptState);
  restoreState(&mainState);
}
Ejemplo n.º 4
0
/* go to background: TSR */
void
msdosBackground(void) {
  saveState(&mainState);
  if (!setjmp(mainCtx)) {
    __dpmi_regs regs;

    /* set a chained Protected Mode Timer IRQ handler */
    timerSeginfo.pm_selector = _my_cs();
    timerSeginfo.pm_offset = (unsigned long)&timerInt;
    _go32_dpmi_get_protected_mode_interrupt_vector(TIMER_INT, &origTimerSeginfo);
    _go32_dpmi_chain_protected_mode_interrupt_vector(TIMER_INT, &timerSeginfo);

    /* set a real mode DOS Idle handler which calls back our Idle handler */
    idleSeginfo.pm_selector = _my_cs();
    idleSeginfo.pm_offset = (unsigned long)&idleInt;
    memset(&idleRegs, 0, sizeof(idleRegs));
    _go32_dpmi_get_real_mode_interrupt_vector(IDLE_INT, &origIdleSeginfo);
    _go32_dpmi_allocate_real_mode_callback_iret(&idleSeginfo, &idleRegs);
    _go32_dpmi_set_real_mode_interrupt_vector(IDLE_INT, &idleSeginfo);

    /* Get InDos and Critical flags addresses */
    regs.h.ah = 0x34;
    __dpmi_int(DOS_INT, &regs);
    inDosOffset = regs.x.es*16 + regs.x.bx;

    regs.x.ax = 0x5D06;
    __dpmi_int(DOS_INT, &regs);
    criticalOffset = regs.x.ds*16 + regs.x.si;

    /* We are ready */
    atexit(tsr_exit);
    backgrounded = 1;

    regs.x.ax = 0x3100;
    regs.x.dx = (/* PSP */ 256 + _go32_info_block.size_of_transfer_buffer) / 16;
    __dpmi_int(DOS_INT, &regs);

    /* shouldn't be reached */
    logMessage(LOG_ERR,"Installation failed");
    backgrounded = 0;
  }
  saveState(&intState);
  restoreState(&mainState);
}
Ejemplo n.º 5
0
/* init_mouse:
 *  Helper for initialising the int 0x33 driver and installing an RMCB.
 */
static int init_mouse(void (*handler)(__dpmi_regs *r))
{
   __dpmi_regs r;
   int num_buttons;

   /* initialise the int 0x33 driver */
   r.x.ax = 0;
   __dpmi_int(0x33, &r); 

   if (r.x.ax == 0)
      return -1;

   num_buttons = r.x.bx;
   if (num_buttons == 0xFFFF)
      num_buttons = 2;

   /* create and activate a real mode callback */
   if (handler) {
      LOCK_VARIABLE(mouse_regs);

      #ifdef ALLEGRO_DJGPP

	 /* djgpp version uses libc routines to set up the RMCB */
	 {
	    LOCK_VARIABLE(mouse_seginfo);

	    mouse_seginfo.pm_offset = (int)handler;
	    mouse_seginfo.pm_selector = _my_cs();

	    if (_go32_dpmi_allocate_real_mode_callback_retf(&mouse_seginfo, &mouse_regs) != 0)
	       return -1;

	    r.x.ax = 0x0C;
	    r.x.cx = 0x7F;
	    r.x.dx = mouse_seginfo.rm_offset;
	    r.x.es = mouse_seginfo.rm_segment;
	    __dpmi_int(0x33, &r);
	 }

      #elif defined ALLEGRO_WATCOM

	 /* Watcom version relies on the DOS extender to do it for us */
	 {
	    struct SREGS sregs;
	    union REGS inregs, outregs;

	    inregs.w.ax = 0x0C;
	    inregs.w.cx = 0x7F;
	    inregs.x.edx = _allocate_real_mode_callback(handler, &mouse_regs);
	    segread(&sregs);
	    sregs.es = _my_cs();
	    int386x(0x33, &inregs, &outregs, &sregs);
	 }

      #else
	 #error unknown platform
      #endif
   }

   return num_buttons;
}
Ejemplo n.º 6
0
/* _install_irq:
 *  Installs a hardware interrupt handler for the specified irq, allocating
 *  an asm wrapper function which will save registers and handle the stack
 *  switching. The C function should return zero to exit the interrupt with
 *  an iret instruction, and non-zero to chain to the old handler.
 */
int _install_irq ( int irq, int (*handler)(void) )
{
	int	c ;

	if ( irq_virgin ) {		/* first time we've been called? */
		unsigned char *p ;

#if defined(__WATCOMC__) && !defined(__386__)
		/* must keep SEGMENT(_isr_stack) == SS for C/L/H module */
		p = NormalizeEven(_isr_stack) + IRQ_STACKS*STACK_SIZE ;
#else
		p = (unsigned char*)malloc(IRQ_STACKS*STACK_SIZE) ;
		if ( p == NULL ) return -1 ;
    #if defined(__386__)
		_lock_data(p,IRQ_STACKS*STACK_SIZE) ;
		p = (unsigned char*)((int)(p+IRQ_STACKS*STACK_SIZE-15) & (~3)) ;
    #else
		p = NormalizeEven(p) + IRQ_STACKS*STACK_SIZE ;
    #endif
#endif
		for ( c = IRQ_STACKS ; --c >= 0 ; ) {
			_irq_stack[c] = p ;
			/* WATCOM C/Large data: p can't be normalized */
			p -= STACK_SIZE ;
		}

#if defined(__DJGPP__)
		_lock_data(&sldata,LOCKED_DATA_SIZE) ;
		_lock_code(&sltext,LOCKED_TEXT_SIZE) ;
#endif

		LOCK_VARIABLE(_irq_handler) ;
		LOCK_VARIABLE(_irq_stack) ;
		LOCK_FUNCTION(_irq_wrapper_0) ;

		for ( c = 0 ; c < MAX_IRQS ; c++ ) {
			_irq_handler[c].handler = NULL ;
			_irq_handler[c].irq = -1 ;
		}

		irq_virgin = 0 ;
	}

	for ( c = 0 ; c < MAX_IRQS ; c++ ) {
		if ( _irq_handler[c].handler == NULL ) {
			ISR	addr ;
			int	vector = irq + (irq < 8 ? 8 : 0x70-8) ;

			_irq_handler[c].handler = handler ;
			_irq_handler[c].irq = irq ;

#if defined(__DJGPP__)	/* or PMODE/W, but not DOS4G/W */
			addr.selector = _my_cs() ;
			switch ( c ) {
			    case 0 :
				addr.offset32 = (long)_irq_wrapper_0 ;
				break ;
			    case 1 :
				addr.offset32 = (long)_irq_wrapper_1 ;
				break ;
			    case 2 :
				addr.offset32 = (long)_irq_wrapper_2 ;
				break ;
			    case 3 :
				addr.offset32 = (long)_irq_wrapper_3 ;
				break ;
			}
			_pm_getvect(vector,&_irq_handler[c].old_vector) ;
			_pm_setvect(vector,&addr) ;
#else
			switch ( c ) {
			    case 0 :
				addr = (ISR)_irq_wrapper_0 ;
				break ;
			    case 1 :
				addr = (ISR)_irq_wrapper_1 ;
				break ;
			    case 2 :
				addr = (ISR)_irq_wrapper_2 ;
				break ;
			    case 3 :
				addr = (ISR)_irq_wrapper_3 ;
				break ;
			}
			_irq_handler[c].old_vector = _dos_getvect(vector) ;
			_dos_setvect(vector,addr) ;
#endif
			return 0 ;
		}
	}

	return -1 ;
}
Ejemplo n.º 7
0
	int _lock_code ( void *_lockaddr, unsigned long _locksize )
	{
		return _lock_memory(_my_cs(),_lockaddr,_locksize) ;
	}