static int install(void) { _go32_dpmi_seginfo info; info.pm_offset = (unsigned)&handler; _go32_dpmi_get_real_mode_interrupt_vector(0x10, &handler_old); _go32_dpmi_allocate_real_mode_callback_raw_with_stack(&info, &handler_regs, handler_stack, sizeof(handler_stack)); _go32_dpmi_set_real_mode_interrupt_vector(0x10, &info); return 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, ®s); inDosFlagPointer = msdosMakeAddress(regs.x.es, regs.x.bx); regs.x.ax = 0X5D06; __dpmi_int(DOS_INTERRUPT, ®s); 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, ®s.x.dx, NULL); __dpmi_int(DOS_INTERRUPT, ®s); /* shouldn't be reached */ logMessage(LOG_ERR, "TSR installation failed"); isBackgrounded = 0; } saveState(&interruptState); restoreState(&mainState); }
/* 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, ®s); inDosOffset = regs.x.es*16 + regs.x.bx; regs.x.ax = 0x5D06; __dpmi_int(DOS_INT, ®s); 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, ®s); /* shouldn't be reached */ logMessage(LOG_ERR,"Installation failed"); backgrounded = 0; } saveState(&intState); restoreState(&mainState); }
/* install the real-mode critical error handler */ void hard_error_catch_setup(void) { /* On first call, allocate some DOS memory and copy the handler into it */ if(!handler_installed) { handler_installed = TRUE; new_handler_info.size = old_handler_info.size = 1; if (_go32_dpmi_allocate_dos_memory(&new_handler_info) != 0) { fprintf(stderr,"Couldn't allocate handler memory\n"); exit(1); } dosmemput(handler, 16, new_handler_info.rm_segment * 16); #ifdef XDEBUG sprintf(Tempbuf, "Handler at segment %x", new_handler_info.rm_segment); error_msg(Tempbuf, 0); #endif } _go32_dpmi_get_real_mode_interrupt_vector(0x24, &old_handler_info); _go32_dpmi_set_real_mode_interrupt_vector(0x24, &new_handler_info); clear_hard_error(); return; }
void want_ctrl_c(int yes) { if (yes) { if (ctrl_c_hooked) return; _go32_dpmi_get_real_mode_interrupt_vector(0x23, &old_vector); new_vector.pm_offset = (int) ctrl_c_isr; _go32_dpmi_allocate_real_mode_callback_iret(&new_vector, ®s); _go32_dpmi_set_real_mode_interrupt_vector(0x23, &new_vector); ctrl_c_count = 0; ctrl_c_hooked = 1; } else { if (!ctrl_c_hooked) return; _go32_dpmi_set_real_mode_interrupt_vector(0x23, &old_vector); _go32_dpmi_free_real_mode_callback(&new_vector); ctrl_c_count = 0; ctrl_c_hooked = 0; } }